<!--   ***********  Web Authentication - Level 2 - Spec source file ***********
Notes:
* the h1 tag is spec title that is rendered within the document window. Wrapping
  may be controlled with break tags.  The spec 'Level' value is not appended.
* the Title metadata value is what is rendered in the browser's titlebar, any break
  tags will be rendered. It also has the spec 'Level' value (gratuitously) appended.
-->

<h1>Web Authentication:<br>An API for accessing Public Key Credentials<br>Level 2</h1>
<pre class='metadata'>
Title: Web Authentication: An API for accessing Public Key Credentials - Level
Status: ED
Prepare for TR: true
TR: https://www.w3.org/TR/webauthn-2/
ED: https://w3c.github.io/webauthn/
Previous Version: https://www.w3.org/TR/2019/PR-webauthn-20190117/
Previous Version: https://www.w3.org/TR/2018/CR-webauthn-20180807/
Previous Version: https://www.w3.org/TR/2018/CR-webauthn-20180320/
Previous Version: https://www.w3.org/TR/2018/WD-webauthn-20180315/
Previous Version: https://www.w3.org/TR/2018/WD-webauthn-20180306/
Previous Version: https://www.w3.org/TR/2017/WD-webauthn-20171205/
Previous Version: https://www.w3.org/TR/2017/WD-webauthn-20170811/
Previous Version: https://www.w3.org/TR/2017/WD-webauthn-20170505/
Previous Version: https://www.w3.org/TR/2017/WD-webauthn-20170216/
Previous Version: https://www.w3.org/TR/2016/WD-webauthn-20161207/
Previous Version: https://www.w3.org/TR/2016/WD-webauthn-20160928/
Previous Version: https://www.w3.org/TR/2016/WD-webauthn-20160902/
Previous Version: https://www.w3.org/TR/2016/WD-webauthn-20160531/
Shortname: webauthn
Level: 2
Editor: Dirk Balfanz, w3cid 47648, Google, balfanz@google.com
Editor: Alexei Czeskis, w3cid 87258, Google, aczeskis@google.com
Editor: Jeff Hodges, w3cid 43843, Google, jdhodges@google.com
Editor: J.C. Jones, w3cid 87240, Mozilla, jc@mozilla.com
Editor: Michael B. Jones, w3cid 38745, Microsoft, mbj@microsoft.com
Editor: Akshay Kumar, w3cid 99318, Microsoft, akshayku@microsoft.com
Editor: Rolf Lindemann, w3cid 84447, Nok Nok Labs, rolf@noknok.com
Editor: Emil Lundberg, Yubico, emil@yubico.com
Former Editor: Vijay Bharadwaj, w3cid 55440, Microsoft, vijay.bharadwaj@microsoft.com
Former Editor: Arnar Birgisson, w3cid 87332, Google, arnarb@google.com
Former Editor: Hubert Le Van Gong, w3cid 84817, PayPal, hlevangong@paypal.com
Former Editor: Angelo Liao, w3cid 94342, Microsoft, huliao@microsoft.com
!Contributors: <a href="mailto:cbrand@google.com">Christiaan Brand</a> (Google)
!Contributors: <a href="mailto:agl@google.com">Adam Langley</a> (Google)
!Contributors: <a href="mailto:mandyam@qti.qualcomm.com">Giridhar Mandyam</a> (Qualcomm)
!Contributors: <a href="mailto:nsatragno@google.com">Nina Satragno</a> (Google)
!Contributors: <a href="mailto:sweeden@au1.ibm.com">Shane Weeden</a> (IBM)
!Contributors: <a href="mailto:mkwst@google.com">Mike West</a> (Google)
!Contributors: <a href="mailto:jyasskin@google.com">Jeffrey Yasskin</a> (Google)
group: webauthn
Issue Tracking: GitHub https://github.com/w3c/webauthn/issues
!Tests: <a href=https://github.com/web-platform-tests/wpt/tree/master/webauthn>web-platform-tests webauthn/</a> (<a href=https://github.com/web-platform-tests/wpt/labels/webauthn>ongoing work</a>)
Text Macro: FALSE <code>false</code>
Text Macro: PII personally identifying information
Text Macro: RP Relying Party
Text Macro: RPS Relying Parties
Text Macro: INFORMATIVE <em>This section is not normative.</em>
Text Macro: TRUE <code>true</code>
Text Macro: WAA WebAuthn Authenticator
Text Macro: WAC WebAuthn Client
Text Macro: WRP WebAuthn Relying Party
Text Macro: WRPS WebAuthn Relying Parties
Ignored Vars: op, alg, type, algorithm
Abstract: This specification defines an API enabling the creation and use of strong, attested, [=scoped=], public key-based
 credentials by [=web applications=], for the purpose of strongly authenticating users. Conceptually, one or more [=public key
 credentials=], each [=scoped=] to a given [=WebAuthn Relying Party=], are created by and [=bound credential|bound=] to
 [=authenticators=] as requested by the web application. The user agent mediates access to [=authenticators=] and their [=public
 key credentials=] in order to preserve user
 privacy. [=Authenticators=] are responsible for ensuring that no operation is performed without [=user consent=].
 [=Authenticators=] provide cryptographic proof of their properties to [=Relying Parties=] via [=attestation=]. This
 specification also describes the functional model for WebAuthn conformant [=authenticators=], including their signature and
 [=attestation=] functionality.
Boilerplate: omit conformance, omit feedback-header, omit abstract-header
Markup Shorthands: css off, markdown on
</pre>

<style type="text/css">
body {
    counter-reset: table;
}
/* For some reason, doing the counter-increment on the figcaption like Bikeshed does with figures does not seem to work here. */
figure.table {
    counter-increment: table;
}
figure.table figcaption {
    counter-increment: none;
}
figure.table figcaption:not(.no-marker)::before {
    content: "Table " counter(table) " ";
}
figure.table .overlarge {
    max-width: 50em;
}

.figure-num-following::before {
    counter-increment: figure;
    content: counter(figure)
}

.figure-num-following::after {
    counter-increment: figure -1;
    content: ""
}

.table-ref-previous::before {
    content: counter(table);
}

.table-ref-following::before {
    counter-increment: table;
    content: counter(table);
}

.table-ref-following::after {
    counter-increment: table -1;
    content: "";
}
</style>


<pre class="link-defaults">

spec: dom; type: interface; for:/; text: Document


</pre>



<!-- TODO: Clean out these anchor lists once they appear in Shepherd -->
<pre class="anchors">

spec: ECMAScript; urlPrefix: https://tc39.github.io/ecma262/#
    type: method
        for: JSON; text: stringify; url: sec-json.stringify
    type: dfn
        text: %ArrayBuffer%; url: sec-arraybuffer-constructor
        url: sec-object-internal-methods-and-internal-slots
            text: internal method
            text: internal slot
        text: own property; url: sec-own-property

spec: RFC8152; urlPrefix: https://tools.ietf.org/html/rfc8152
    type: dfn
        text: Section 7; url: section-7
        text: Section 13.1; url: section-13.1
        text: Section 8.1; url: section-8.1

spec: RFC8230; urlPrefix: https://tools.ietf.org/html/rfc8230
    type: dfn
        text: Section 4; url: section-4
        text: Section 2; url: section-2

spec: html; urlPrefix: https://html.spec.whatwg.org/multipage/
    type: dfn
        urlPrefix: dom.html
            for: Document; url: concept-document-feature-policy; text: feature policy
        urlPrefix: browsers.html
            text: browsing context; url: browsing-context
        urlPrefix: origin.html
            text: origin; url: concept-origin
            text: opaque origin; url: concept-origin-opaque
            text: tuple origin; url: concept-origin-tuple
            text: document.domain; url:dom-document-domain

spec: url; urlPrefix: https://url.spec.whatwg.org
    type: dfn
        text: scheme; url: concept-url-scheme
        text: port; url: concept-url-port


spec: TokenBinding; urlPrefix: https://tools.ietf.org/html/rfc8471#
    type: dfn
        text: Token Binding; url: section-1
        text: Token Binding ID; url: section-3.2

spec: credential-management-1; urlPrefix: https://w3c.github.io/webappsec-credential-management/
    type: dictionary
        text: CredentialCreationOptions; url: dictdef-credentialcreationoptions
    type: dictionary
        text: CredentialRequestOptions; url: dictdef-credentialrequestoptions
    for: Credential
        type: method
            text: [[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)
            text: [[Create]](origin, options, sameOriginWithAncestors)
            text: [[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
            text: [[Store]](credential, sameOriginWithAncestors)
    for: CredentialsContainer
        type: method
            text: create(); url: dom-credentialscontainer-create
    type: dfn
        text: signal
        text: same-origin with its ancestors; url: same-origin-with-its-ancestors

spec: Geolocation-API; urlPrefix: https://w3c.github.io/geolocation-api/
    type: interface
        text: GeolocationCoordinates; url: coordinates_interface

spec: mixed-content; urlPrefix: www.w3.org/TR/mixed-content/
    type: dfn
        text: a priori authenticated

spec: page-visibility; urlPrefix: https://www.w3.org/TR/page-visibility/
    type: dfn
        text: visibility states

spec: WHATWG HTML; urlPrefix: https://html.spec.whatwg.org/
    type: dfn
        text: focus
        text: username; url: attr-fe-autocomplete-username

spec: WHATWG URL; urlPrefix: https://url.spec.whatwg.org/
    type: dfn
        text: same site; url: host-same-site

spec: FIDO-CTAP; urlPrefix: https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-client-to-authenticator-protocol-v2.0-id-20180227.html
    type: dfn
        text: CTAP2 canonical CBOR encoding form; url: ctap2-canonical-cbor-encoding-form
        text: §6.2. Responses; url: responses

spec: FIDO-APPID; urlPrefix: https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-appid-and-facets-v2.0-id-20180227.html
    type: dfn
        text: determining the FacetID of a calling application; url: determining-the-facetid-of-a-calling-application
        text: determining if a caller's FacetID is authorized for an AppID; url: determining-if-a-caller-s-facetid-is-authorized-for-an-appid

spec: FIDO-U2F-Message-Formats; urlPrefix: https://fidoalliance.org/specs/fido-u2f-v1.1-id-20160915/fido-u2f-raw-message-formats-v1.1-id-20160915.html
    type: dfn
        text: application parameter; url: authentication-request-message---u2f_authenticate
        text: Section 4.3; url: registration-response-message-success
        text: Section 5.4; url: authentication-response-message-success

spec: FIDO-Registry; urlPrefix: https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-registry-v2.0-id-20180227.html
    type: dfn
        text: Section 3.1 User Verification Methods; url: user-verification-methods
        text: Section 3.2 Key Protection Types; url: key-protection-types
        text: Section 3.3 Matcher Protection Types; url: matcher-protection-types
        text: Section 3.6.2 Public Key Representation Formats; url: public-key-representation-formats

spec: RFC4949; urlPrefix: https://tools.ietf.org/html/rfc4949
    type: dfn
        text: leap of faith; url: page-182
        text: man-in-the-middle attack; url: page-186
        text: salt; url: page-258
        text: salted; url: page-258

spec: SP800-800-63r3; urlPrefix: https://pages.nist.gov/800-63-3/sp800-63-3.html
    type: dfn
        text: authentication factor; url: af
        text: multi-factor; url: af
        text: second-factor; url: af
        text: single-factor; url: sf
        text: something you know; url: af
        text: something you have; url: af
        text: something you are; url: af

spec: webidl; urlPrefix: https://heycam.github.io/webidl
    type: dfn;
        text: get a copy of the bytes held by the buffer source; url: dfn-get-buffer-source-reference

spec: webdriver; urlPrefix: https://w3c.github.io/webdriver/webdriver-spec.html#
    type: dfn
        text: WebDriver error; url: dfn-error
        text: WebDriver error code; url: dfn-error-code
        text: extension command; url: dfn-extension-command
        text: extension command name; url: dfn-extension-command-name
        text: getting a property; url: dfn-getting-properties
        text: set a property; url: dfn-set-a-property
        text: prefix; url: dfn-url-prefix
        text: invalid argument; url: dfn-invalid-argument
        text: local end; url: dfn-local-end
        text: remote end steps; url: dfn-remote-end-steps
        text: session; url: dfn-session
        text: success; url: dfn-success
        text: trying; url: dfn-try

spec: UTR29
    urlPrefix: https://unicode.org/reports/tr29/
        type: dfn; for:/; url: Grapheme_Cluster_Boundaries; text: grapheme cluster

</pre> <!-- class=anchors -->

<!-- L128 spec:webappsec-credential-management-1; type:dictionary; for:/; text:CredentialRequestOptions -->

<pre class="link-defaults">
spec:credential-management; type:dfn; text:credentials
spec:html; type:dfn; for:environment settings object; text:global object
spec:infra; type:dfn; for:/; text:set
spec:infra; type:dfn; text:list
spec:infra; type:dfn; for:struct; text:item
spec:infra; type:dfn; for:map-exists; text:exists
spec:url; type:dfn; text:domain
spec:url; type:dfn; for:url; text:host
spec:url; type:dfn; text:valid domain;
spec:webidl; type:dfn; text:DOMString
spec:webidl; type:interface; text:Promise
</pre>


# Introduction # {#sctn-intro}

[INFORMATIVE]

This specification defines an API enabling the creation and use of strong, attested, [=scoped=], public key-based
credentials by [=web applications=], for the purpose of strongly authenticating users. A [=public key credential=] is
created and stored by a <em>[=[WAA]=]</em> at the behest of a <em>[=[WRP]=]</em>, subject to <em>[=user
consent=]</em>. Subsequently, the [=public key credential=] can only be accessed by [=origins=] belonging to that [=[RP]=].
This scoping is enforced jointly by <em>[=conforming User Agents=]</em> and <em>[=authenticators=]</em>.
Additionally, privacy across [=[RPS]=] is maintained; [=[RPS]=] are not able to detect any properties, or even
the existence, of credentials [=scoped=] to other [=[RPS]=].

[=[RPS]=] employ the [=Web Authentication API=] during two distinct, but related, [=ceremonies=] involving a user. The first
is [=Registration=], where a [=public key credential=] is created on an [=authenticator=], and [=scoped=] to a [=[RP]=]
with the present user's account (the account might already exist or might be created at this time). The second is
[=Authentication=], where the [=[RP]=] is presented with an <em>[=Authentication Assertion=]</em> proving the presence
and [=user consent|consent=] of the user who registered the [=public key credential=]. Functionally, the [=Web Authentication
API=] comprises a {{PublicKeyCredential}} which extends the Credential Management API [[!CREDENTIAL-MANAGEMENT-1]], and
infrastructure which allows those credentials to be used with {{CredentialsContainer/create()|navigator.credentials.create()}} and
{{CredentialsContainer/get()|navigator.credentials.get()}}. The former is used during [=Registration=], and the
latter during [=Authentication=].

Broadly, compliant [=authenticators=] protect [=public key credentials=], and interact with user agents to implement the
[=Web Authentication API=].
Implementing compliant authenticators is possible in software executing
(a) on a general-purpose computing device,
(b) on an on-device Secure Execution Environment, Trusted Platform Module (TPM), or a Secure Element (SE), or
(c) off device.
Authenticators being implemented on device are called [=platform authenticators=].
Authenticators being implemented off device ([=roaming authenticators=]) can be accessed over a transport such
as Universal Serial Bus (USB), Bluetooth Low Energy (BLE), or Near Field Communications (NFC).

## Specification Roadmap ## {#sctn-spec-roadmap}

While many W3C specifications are directed primarily to user agent developers and also to web application developers
(i.e., "Web authors"), the nature of Web Authentication requires that this specification be correctly used by multiple audiences,
as described below.

**All audiences** ought to begin with [[#sctn-use-cases]], [[#sctn-sample-scenarios]], and [[#sctn-terminology]], and should also
refer to [[WebAuthnAPIGuide]] for an overall tutorial.
Beyond that, the intended audiences for this document are the following main groups:

- [=[RP]=] web application developers, expecially those responsible for [=[RP]=] [=web application=] login flows, account recovery flows,
    user account database content, etc.
- Web framework developers

    - The above two audiences should in particular refer to [[#sctn-rp-operations]].
        The introduction to [[#sctn-api]] may be helpful, though readers should realize that the [[#sctn-api]] section is targeted specifically
        at user agent developers, not web application developers.
        Additionally, if they intend to verify [=authenticator=] [=attestations=], then
        [[#sctn-attestation]] and [[#sctn-defined-attestation-formats]] will also be relevant.
        [[#sctn-extensions]], and [[#sctn-defined-extensions]] will be of interest if they wish to make use of extensions.
        Finally, they should read [[#sctn-security-considerations-rp]] and [[#sctn-privacy-considerations-rp]]
        and consider which challenges apply to their application and users.

- User agent developers
- OS platform developers, responsible for OS platform API design and implementation in regards to platform-specific
    [=authenticator=] APIs, platform [=WebAuthn Client=] instantiation, etc.

    - The above two audiences should read [[#sctn-api]] very carefully, along with [[#sctn-extensions]] if they intend to support extensions.
        They should also carefully read [[#sctn-security-considerations-client]] and [[#sctn-privacy-considerations-client]].

- [=Authenticator=] developers. These readers will want to pay particular attention to [[#sctn-authenticator-model]],
    [[#sctn-defined-attestation-formats]], [[#sctn-extensions]], and [[#sctn-defined-extensions]].
    They should also carefully read [[#sctn-security-considerations-authenticator]] and [[#sctn-privacy-considerations-authenticator]].

<div class="note">
    Note: Along with the [[#sctn-api|Web Authentication API]] itself, this specification defines a
    request-response <em>cryptographic protocol</em>&mdash;the
    <dfn export>WebAuthn/FIDO2 protocol</dfn>&mdash;between
    a [=[WRP]=] server and an [=authenticator=], where the [=[RP]=]'s request consists of a
    [[#sctn-cryptographic-challenges|challenge]] and other
    input data supplied by the [=[RP]=] and sent to the [=authenticator=].
    The request is conveyed via the
    combination of HTTPS, the [=[RP]=] [=web application=], the [[#sctn-api|WebAuthn API]], and the platform-specific communications channel
    between the user agent and the [=authenticator=].
    The [=authenticator=] replies with a digitally signed [=authenticator data=] message and other output data, which is conveyed back to the
    [=[RP]=] server via the same path in reverse. Protocol details vary according to whether an [=authentication=] or
    [=registration=] operation is invoked by the [=[RP]=].
    See also [Figure 1](#fig-registration) and [Figure 2](#fig-authentication).

    <strong>It is important for Web Authentication deployments' end-to-end security</strong> that the role of each
    component&mdash;the [=[RP]=] server, the [=client=], and the [=authenticator=]&mdash;
    as well as [[#sctn-security-considerations]] and [[#sctn-privacy-considerations]], are understood <em>by all audiences</em>.
</div>

## Use Cases ## {#sctn-use-cases}

The below use case scenarios illustrate use of two very different types of [=authenticators=], as well as outline further
scenarios. Additional scenarios, including sample code, are given later in [[#sctn-sample-scenarios]].

### Registration ### {#sctn-usecase-registration}

- On a phone:
    * User navigates to example.com in a browser and signs in to an existing account using whatever method they have been using
        (possibly a legacy method such as a password), or creates a new account.
    * The phone prompts, "Do you want to register this device with example.com?"
    * User agrees.
    * The phone prompts the user for a previously configured [=authorization gesture=] (PIN, biometric, etc.); the user
        provides this.
    * Website shows message, "Registration complete."


### Authentication ### {#sctn-usecase-authentication}

- On a laptop or desktop:
    * User pairs their phone with the laptop or desktop via Bluetooth.
    * User navigates to example.com in a browser and initiates signing in.
    * User gets a message from the browser, "Please complete this action on your phone."

- Next, on their phone:
    * User sees a discrete prompt or notification, "Sign in to example.com."
    * User selects this prompt / notification.
    * User is shown a list of their example.com identities, e.g., "Sign in as Alice / Sign in as Bob."
    * User picks an identity, is prompted for an [=authorization gesture=] (PIN, biometric, etc.) and provides this.

- Now, back on the laptop:
    * Web page shows that the selected user is signed in, and navigates to the signed-in page.


### New Device Registration ### {#sctn-usecase-new-device-registration}

This use case scenario illustrates how a [=[RP]=] can leverage a combination of a [=roaming authenticator=] (e.g., a USB security
key fob) and a [=platform authenticator=] (e.g., a built-in fingerprint sensor) such that the user has:

  - a "primary" [=roaming authenticator=] that they use to authenticate on new-to-them [=client devices=] (e.g., laptops,
    desktops) or on such [=client devices=] that lack a [=platform authenticator=], and
  - a low-friction means to strongly re-authenticate on [=client devices=] having [=platform authenticators=].

Note: This approach of registering multiple [=authenticators=] for an account is also useful in account recovery use cases.

- First, on a desktop computer (lacking a [=platform authenticator=]):
    * User navigates to `example.com` in a browser and signs in to an existing account using whatever method they have been using
        (possibly a legacy method such as a password), or creates a new account.
    * User navigates to account security settings and selects "Register security key".
    * Website prompts the user to plug in a USB security key fob; the user does.
    * The USB security key blinks to indicate the user should press the button on it; the user does.
    * Website shows message, "Registration complete."

    Note: Since this computer lacks a [=platform authenticator=], the website may require the user to present their USB security
    key from time to time or each time the user interacts with the website. This is at the website's discretion.

- Later, on their laptop (which features a [=platform authenticator=]):
    * User navigates to example.com in a browser and initiates signing in.
    * Website prompts the user to plug in their USB security key.
    * User plugs in the previously registered USB security key and presses the button.
    * Website shows that the user is signed in, and navigates to the signed-in page.
    * Website prompts, "Do you want to register this computer with example.com?"
    * User agrees.
    * Laptop prompts the user for a previously configured [=authorization gesture=] (PIN, biometric, etc.); the user provides this.
    * Website shows message, "Registration complete."
    * User signs out.

- Later, again on their laptop:
    * User navigates to example.com in a browser and initiates signing in.
    * Website shows message, "Please follow your computer's prompts to complete sign in."
    * Laptop prompts the user for an [=authorization gesture=] (PIN, biometric, etc.); the user provides this.
    * Website shows that the user is signed in, and navigates to the signed-in page.


### Other Use Cases and Configurations ### {#sctn-other-configurations}

A variety of additional use cases and configurations are also possible, including (but not limited to):

- A user navigates to example.com on their laptop, is guided through a flow to create and register a credential on their phone.

- A user obtains a discrete, [=roaming authenticator=], such as a "fob" with USB or USB+NFC/BLE connectivity options, loads
    example.com in their browser on a laptop or phone, and is guided through a flow to create and register a credential on the
    fob.

- A [=[RP]=] prompts the user for their [=authorization gesture=] in order to authorize a single transaction, such as a payment
    or other financial transaction.




## Sample API Usage Scenarios ## {#sctn-sample-scenarios}

[INFORMATIVE]

In this section, we walk through some events in the lifecycle of a [=public key credential=], along with the corresponding
sample code for using this API. Note that this is an example flow and does not limit the scope of how the API can be used.

As was the case in earlier sections, this flow focuses on a use case involving a [=first-factor roaming authenticator=]
with its own display. One example of such an authenticator would be a smart phone. Other authenticator types are also supported
by this API, subject to implementation by the [=client platform=]. For instance, this flow also works without modification for the case of
an authenticator that is embedded in the [=client device=]. The flow also works for the case of an authenticator without
its own display (similar to a smart card) subject to specific implementation considerations. Specifically, the [=client platform=]
needs to display any prompts that would otherwise be shown by the authenticator, and the authenticator needs to allow the [=client
platform=] to enumerate all the authenticator's credentials so that the client can have information to show appropriate prompts.


### Registration ### {#sctn-sample-registration}

This is the first-time flow, in which a new credential is created and registered with the server.
In this flow, the [=[WRP]=] does not have a preference for [=platform authenticator=] or [=roaming authenticators=].

1. The user visits example.com, which serves up a script. At this point, the user may already be logged in using a legacy
    username and password, or additional authenticator, or other means acceptable to the [=[RP]=].
    Or the user may be in the process of creating a new account.

1. The [=[RP]=] script runs the code snippet below.

1. The [=client platform=] searches for and locates the authenticator.

1. The [=client=] connects to the authenticator, performing any pairing actions if necessary.

1. The authenticator shows appropriate UI for the user to provide a biometric or other [=authorization gesture=].

1. The authenticator returns a response to the [=client=], which in turn returns a response to the [=[RP]=] script. If
    the user declined to select an authenticator or provide authorization, an appropriate error is returned.

1. If a new credential was created,
    - The [=[RP]=] script sends the newly generated [=credential public key=] to the server, along with additional information
        such as attestation regarding the provenance and characteristics of the authenticator.
    - The server stores the [=credential public key=] in its database and associates it with the user as well as with the
        characteristics of authentication indicated by attestation, also storing a friendly name for later use.
    - The script may store data such as the [=credential ID=] in local storage, to improve future UX by narrowing the choice of
        credential for the user.

The sample code for generating and registering a new key follows:

<pre class="example" highlight="js">
    if (!window.PublicKeyCredential) { /* Client not capable. Handle error. */ }

    var publicKey = {
      // The challenge is produced by the server; see the Security Considerations
      challenge: new Uint8Array([21,31,105 /* 29 more random bytes generated by the server */]),

      // Relying Party:
      rp: {
        name: "ACME Corporation"
      },

      // User:
      user: {
        id: Uint8Array.from(window.atob("MIIBkzCCATigAwIBAjCCAZMwggE4oAMCAQIwggGTMII="), c=>c.charCodeAt(0)),
        name: "alex.p.mueller@example.com",
        displayName: "Alex P. Müller",
      },

      // This Relying Party will accept either an ES256 or RS256 credential, but
      // prefers an ES256 credential.
      pubKeyCredParams: [
        {
          type: "public-key",
          alg: -7 // "ES256" as registered in the IANA COSE Algorithms registry
        },
        {
          type: "public-key",
          alg: -257 // Value registered by this specification for "RS256"
        }
      ],

      authenticatorSelection: {
        // Try to use UV if possible. This is also the default.
        userVerification: "preferred"
      },

      timeout: 360000,  // 6 minutes
      excludeCredentials: [], // No exclude list of PKCredDescriptors
      extensions: {"loc": true}  // Include location information
                                               // in attestation
    };

    // Note: The following call will cause the authenticator to display UI.
    navigator.credentials.create({ publicKey })
      .then(function (newCredentialInfo) {
        // Send new credential info to server for verification and registration.
      }).catch(function (err) {
        // No acceptable authenticator or user refused consent. Handle appropriately.
      });
</pre>

### Registration Specifically with User-Verifying Platform Authenticator ### {#sctn-sample-registration-with-platform-authenticator}

This is an example flow for when the [=[WRP]=] is specifically interested in creating a [=public key credential=] with
a [=user-verifying platform authenticator=].

1. The user visits example.com and clicks on the login button, which redirects the user to login.example.com.

1. The user enters a username and password to log in. After successful login, the user is redirected back to example.com.

1. The [=[RP]=] script runs the code snippet below.

    1. The user agent checks if a [=user-verifying platform authenticator=] is available. If not, terminate this flow.

    1. The [=[RP]=] asks the user if they want to create a credential with it. If not, terminate this flow.

    1. The user agent and/or operating system shows appropriate UI and guides the user in creating a credential
        using one of the available platform authenticators.

    1. Upon successful credential creation, the [=[RP]=] script conveys the new credential to the server.

<pre class="example" highlight="js">
    if (!window.PublicKeyCredential) { /* Client not capable of the API. Handle error. */ }

    PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()
        .then(function (uvpaaAvailable) {
            // If there is a user-verifying platform authenticator
            if (uvpaaAvailable) {
                // Render some RP-specific UI and get a Promise for a Boolean value
                return askIfUserWantsToCreateCredential();
            }
        }).then(function (userSaidYes) {
            // If there is a user-verifying platform authenticator
            // AND the user wants to create a credential
            if (userSaidYes) {
                var publicKeyOptions = { /* Public key credential creation options. */};
                return navigator.credentials.create({ "publicKey": publicKeyOptions });
            }
        }).then(function (newCredentialInfo) {
            if (newCredentialInfo) {
                // Send new credential info to server for verification and registration.
            }
        }).catch(function (err) {
            // Something went wrong. Handle appropriately.
        });
</pre>

### Authentication ### {#sctn-sample-authentication}

This is the flow when a user with an already registered credential visits a website and wants to authenticate using the
credential.

1. The user visits example.com, which serves up a script.

1. The script asks the [=client=] for an Authentication Assertion, providing as much information as possible to narrow
    the choice of acceptable credentials for the user. This can be obtained from the data that was stored locally after
    registration, or by other means such as prompting the user for a username.

1. The [=[RP]=] script runs one of the code snippets below.

1. The [=client platform=] searches for and locates the authenticator.

1. The [=client=] connects to the authenticator, performing any pairing actions if necessary.

1. The authenticator presents the user with a notification that their attention is needed. On opening the
    notification, the user is shown a friendly selection menu of acceptable credentials using the account information provided
    when creating the credentials, along with some information on the [=origin=] that is requesting these keys.

1. The authenticator obtains a biometric or other [=authorization gesture=] from the user.

1. The authenticator returns a response to the [=client=], which in turn returns a response to the [=[RP]=] script.
    If the user declined to select a credential or provide an authorization, an appropriate error is returned.

1. If an assertion was successfully generated and returned,
    - The script sends the assertion to the server.
    - The server examines the assertion, extracts the [=credential ID=], looks up the registered
        credential public key in its database, and verifies the [=assertion signature=].
        If valid, it looks up the identity associated with the assertion's [=credential ID=]; that
        identity is now authenticated. If the [=credential ID=] is not recognized by the server (e.g.,
        it has been deregistered due to inactivity) then the authentication has failed; each [=[RP]=]
        will handle this in its own way.
    - The server now does whatever it would otherwise do upon successful authentication -- return a success page, set
        authentication cookies, etc.

If the [=[RP]=] script does not have any hints available (e.g., from locally stored data) to help it narrow the list of
credentials, then the sample code for performing such an authentication might look like this:

<pre class="example" highlight="js">
    if (!window.PublicKeyCredential) { /* Client not capable. Handle error. */ }

    // credentialId is generated by the authenticator and is an opaque random byte array
    var credentialId = new Uint8Array([183, 148, 245 /* more random bytes previously generated by the authenticator */]);
    var options = {
      // The challenge is produced by the server; see the Security Considerations
      challenge: new Uint8Array([4,101,15 /* 29 more random bytes generated by the server */]),
      timeout: 120000,  // 2 minutes
      allowCredentials: [{ type: "public-key", id: credentialId }]
    };

    navigator.credentials.get({ "publicKey": options })
        .then(function (assertion) {
        // Send assertion to server for verification
    }).catch(function (err) {
        // No acceptable credential or user refused consent. Handle appropriately.
    });
</pre>

On the other hand, if the [=[RP]=] script has some hints to help it narrow the list of credentials, then the sample code for
performing such an authentication might look like the following. Note that this sample also demonstrates how to use the
extension for transaction authorization.

<pre class="example" highlight="js">
    if (!window.PublicKeyCredential) { /* Client not capable. Handle error. */ }

    var encoder = new TextEncoder();
    var acceptableCredential1 = {
        type: "public-key",
        id: encoder.encode("BA44712732CE")
    };
    var acceptableCredential2 = {
        type: "public-key",
        id: encoder.encode("BG35122345NF")
    };

    var options = {
      // The challenge is produced by the server; see the Security Considerations
      challenge: new Uint8Array([8,18,33 /* 29 more random bytes generated by the server */]),
      timeout: 120000,  // 2 minutes
      allowCredentials: [acceptableCredential1, acceptableCredential2],
      extensions: { 'txAuthSimple':
         "Wave your hands in the air like you just don't care" }
    };

    navigator.credentials.get({ "publicKey": options })
        .then(function (assertion) {
        // Send assertion to server for verification
    }).catch(function (err) {
        // No acceptable credential or user refused consent. Handle appropriately.
    });
</pre>

### Aborting Authentication Operations ### {#sctn-sample-aborting}

The below example shows how a developer may use the AbortSignal parameter to abort a
credential registration operation. A similar procedure applies to an authentication operation.

<pre class="example" highlight="js">
    const authAbortController = new AbortController();
    const authAbortSignal = authAbortController.signal;

    authAbortSignal.onabort = function () {
        // Once the page knows the abort started, inform user it is attempting to abort.
    }

    var options = {
        // A list of options.
    }

    navigator.credentials.create({
        publicKey: options,
        signal: authAbortSignal})
        .then(function (attestation) {
            // Register the user.
        }).catch(function (error) {
            if (error == "AbortError") {
                // Inform user the credential hasn't been created.
                // Let the server know a key hasn't been created.
            }
        });

    // Assume widget shows up whenever authentication occurs.
    if (widget == "disappear") {
        authAbortController.abort();
    }
</pre>


### Decommissioning ### {#sctn-sample-decommissioning}

The following are possible situations in which decommissioning a credential might be desired. Note that all of these are
handled on the server side and do not need support from the API specified here.

- Possibility #1 -- user reports the credential as lost.
    * User goes to server.example.net, authenticates and follows a link to report a lost/stolen [=authenticator=].
    * Server returns a page showing the list of registered credentials with friendly names as configured during registration.
    * User selects a credential and the server deletes it from its database.
    * In the future, the [=[RP]=] script does not specify this credential in any list of acceptable credentials, and assertions
        signed by this credential are rejected.

- Possibility #2 -- server deregisters the credential due to inactivity.
    * Server deletes credential from its database during maintenance activity.
    * In the future, the [=[RP]=] script does not specify this credential in any list of acceptable credentials, and assertions
        signed by this credential are rejected.

- Possibility #3 -- user deletes the credential from the [=authenticator=].
    * User employs a [=authenticator=]-specific method (e.g., device settings UI) to delete a credential from their [=authenticator=].
    * From this point on, this credential will not appear in any selection prompts, and no assertions can be generated with it.
    * Sometime later, the server deregisters this credential due to inactivity.


##  Platform-Specific Implementation Guidance ## {#sctn-platform-impl-guidance}

This specification defines how to use Web Authentication in the general case. When using Web
Authentication in connection with specific platform support (e.g. apps), it is recommended to see
platform-specific documentation and guides for additional guidance and limitations.



# Conformance # {#sctn-conformance}

This specification defines three conformance classes. Each of these classes is specified so that conforming members of the class
are secure against non-conforming or hostile members of the other classes.

## User Agents ## {#sctn-conforming-user-agents}

A User Agent MUST behave as described by [[#sctn-api]] in order to be considered conformant. [=Conforming User Agents=] MAY implement
algorithms given in this specification in any way desired, so long as the end result is indistinguishable from the result that
would be obtained by the specification's algorithms.

A conforming User Agent MUST also be a conforming implementation of the IDL fragments of this specification, as described in the
“Web IDL” specification. [[!WebIDL]]

## Authenticators ## {#sctn-conforming-authenticators}

A [=[WAA]=] MUST provide the operations defined by [[#sctn-authenticator-model]], and those operations MUST behave as
described there. This is a set of functional and security requirements for an authenticator to be usable by a [=Conforming User
Agent=].

As described in [[#sctn-use-cases]], an authenticator may be implemented in the operating system underlying the User Agent, or in
external hardware, or a combination of both.

### Backwards Compatibility with FIDO U2F ### {#sctn-conforming-authenticators-u2f}

[=Authenticators=] that only support the [[#sctn-fido-u2f-attestation]] have no mechanism to store a
[=user handle=], so the returned {{AuthenticatorAssertionResponse/userHandle}} will always be null.

## [WRPS] ## {#sctn-conforming-relying-parties}

A [=[WRP]=] MUST behave as described in [[#sctn-rp-operations]] to obtain all the security benefits offered by this specification. See
[[#sctn-rp-benefits]] for further discussion of this.


## All Conformance Classes ## {#sctn-conforming-all-classes}

All [=CBOR=] encoding performed by the members of the above conformance classes MUST be done using the
[=CTAP2 canonical CBOR encoding form=].
All decoders of the above conformance classes SHOULD reject CBOR that is not validly encoded
in the [=CTAP2 canonical CBOR encoding form=] and SHOULD reject messages with duplicate map keys.


# Dependencies # {#sctn-dependencies}

This specification relies on several other underlying specifications, listed
below and in [[#index-defined-elsewhere]].

: Base64url encoding
:: The term <dfn>Base64url Encoding</dfn> refers to the base64 encoding using the URL- and filename-safe character set defined
    in Section 5 of [[!RFC4648]], with all trailing '=' characters omitted (as permitted by Section 3.2) and without the
    inclusion of any line breaks, whitespace, or other additional characters.

: CBOR
:: A number of structures in this specification, including attestation statements and extensions, are encoded using the
    [=CTAP2 canonical CBOR encoding form=] of the Compact Binary Object Representation (<dfn>CBOR</dfn>) [[!RFC7049]],
    as defined in [[!FIDO-CTAP]].

: CDDL
:: This specification describes the syntax of all [=CBOR=]-encoded data using the CBOR Data Definition Language (CDDL) [[!RFC8610]].

: COSE
:: CBOR Object Signing and Encryption (COSE) [[!RFC8152]].  The IANA COSE Algorithms registry established by this specification is also used.

:  Credential Management
:: The API described in this document is an extension of the {{Credential}} concept defined in [[!CREDENTIAL-MANAGEMENT-1]].

: DOM
:: {{DOMException}} and the DOMException values used in this specification are defined in [[!DOM4]].

: ECMAScript
:: [=%ArrayBuffer%=] is defined in [[!ECMAScript]].

: HTML
:: The concepts of [=browsing context=], [=origin=], [=opaque origin=], [=tuple origin=], [=relevant settings object=],
    and [=is a registrable domain suffix of or is equal to=] are defined in [[!HTML]].

: URL
:: The concept of [=same site=] is defined in [[!URL]].

: Web IDL
:: Many of the interface definitions and all of the IDL in this specification depend on [[!WebIDL]]. This updated version of
    the Web IDL standard adds support for {{Promise}}s, which are now the preferred mechanism for asynchronous
    interaction in all new web APIs.

: FIDO AppID
:: The algorithms for [=determining the FacetID of a calling application=] and
    [=determining if a caller's FacetID is authorized for an AppID=] (used only in
    the [=AppID|AppID extension=]) are defined by [[!FIDO-APPID]].

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED",  "MAY", and
"OPTIONAL" in this document are to be interpreted as described in [[!RFC2119]].


# Terminology # {#sctn-terminology}

: <dfn>Attestation</dfn>
:: Generally, <em>attestation</em> is a statement serving to bear witness, confirm, or authenticate.
    In the WebAuthn context, [=attestation=] is employed to <em>attest</em> to the <em>provenance</em> of an [=authenticator=]
    and the data it emits; including, for example: [=credential IDs=], [=credential key pairs=], signature counters, etc. An
    [=attestation statement=] is conveyed in an [=attestation object=] during [=registration=]. See also [[#sctn-attestation]]
    and [Figure 6](#fig-attStructs). Whether or how the [=client=] conveys the [=attestation statement=] and [=AAGUID=]
    portions of the [=attestation object=] to the [=[RP]=] is described by [=attestation conveyance=].

: <dfn>Attestation Certificate</dfn>
:: A X.509 Certificate for the <dfn>attestation key pair</dfn> used by an [=authenticator=] to attest to its manufacture
    and capabilities. At [=registration=] time, the [=authenticator=] uses the <dfn>attestation private key</dfn> to sign
    the [=[RP]=]-specific [=credential public key=] (and additional data) that it generates and returns via the
    [=authenticatorMakeCredential=] operation. [=[RPS]=] use the <dfn>attestation public key</dfn> conveyed in the [=attestation
    certificate=] to verify the [=attestation signature=]. Note that in the case of [=self attestation=], the
    [=authenticator=] has no distinct [=attestation key pair=] nor [=attestation certificate=], see [=self
    attestation=] for details.

: <dfn>Authentication</dfn>
: <dfn>Authentication Ceremony</dfn>
:: The [=ceremony=] where a user, and the user's [=client=] (containing at least one [=authenticator=]) work in
    concert to cryptographically prove to a [=[RP]=] that the user controls the [=credential private key=] of a
    previously-registered [=public key credential=] (see [=Registration=]). Note that this includes a [=test of user presence=] or
    [=user verification=].

: <dfn>Authentication Assertion</dfn>
: <dfn>Assertion</dfn>
:: The cryptographically signed {{AuthenticatorAssertionResponse}} object returned by an [=authenticator=] as the result of an
    [=authenticatorGetAssertion=] operation.

    This corresponds to the [[!CREDENTIAL-MANAGEMENT-1]] specification's single-use <a
    spec="credential-management">credentials</a>.

: <dfn>Authenticator</dfn>
: <dfn>[WAA]</dfn>
:: A cryptographic entity, existing in hardware or software, that can [=registration|register=] a user with a given [=[RP]=]
    and later [=Authentication Assertion|assert possession=] of the registered [=public key credential=], and optionally
    [=user verification|verify the user=], when requested by the [=[RP]=]. [=Authenticators=] can report information
    regarding their [=authenticator types|type=] and security characteristics via [=attestation=] during [=registration=].

    A [=[WAA]=] could be a [=roaming authenticator=], a dedicated hardware subsystem integrated into the [=client device=],
    or a software component of the [=client=] or [=client device=].

    In general, an [=authenticator=] is assumed to have only one user.
    If multiple natural persons share access to an [=authenticator=],
    they are considered to represent the same user in the context of that [=authenticator=].
    If an [=authenticator=] implementation supports multiple users in separated compartments,
    then each compartment is considered a separate [=authenticator=]
    with a single user with no access to other users' [=credentials=].

: <dfn>Authorization Gesture</dfn>
:: An [=authorization gesture=] is a physical interaction performed by a user with an authenticator as part of a [=ceremony=],
    such as [=registration=] or [=authentication=]. By making such an [=authorization gesture=], a user [=user consent|provides
    consent=] for (i.e., <em>authorizes</em>) a [=ceremony=] to proceed. This MAY involve [=user verification=] if the
    employed [=authenticator=] is capable, or it MAY involve a simple [=test of user presence=].

: <dfn>Biometric Recognition</dfn>
:: The automated recognition of individuals based on their biological and behavioral characteristics [[ISOBiometricVocabulary]].

: <dfn>Biometric Authenticator</dfn>
:: Any [=authenticator=] that implements [=biometric recognition=].

: <dfn>Bound credential</dfn>
:: A [=public key credential source=] or [=public key credential=] is said to be [=bound credential|bound=] to its [=managing
    authenticator=]. This means that only the [=managing authenticator=] can generate [=assertions=] for the [=public key
    credential sources=] [=bound credential|bound=] to it.

: <dfn>Ceremony</dfn>
:: The concept of a [=ceremony=] [[Ceremony]] is an extension of the concept of a network protocol, with human nodes alongside
    computer nodes and with communication links that include user interface(s), human-to-human communication, and transfers of
    physical objects that carry data. What is out-of-band to a protocol is in-band to a ceremony. In this specification,
    [=Registration=] and [=Authentication=] are ceremonies, and an [=authorization gesture=] is often a component of
    those [=ceremonies=].

: <dfn>Client</dfn>
: <dfn>[WAC]</dfn>
:: Also referred to herein as simply a [=client=]. See also [=Conforming User Agent=]. A [=[WAC]=] is an intermediary entity typically implemented in the user agent (in whole, or in part). Conceptually, it underlies the [=Web Authentication API=] and embodies the implementation of the {{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)}} and {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)}} [=internal methods=]. It is responsible for both marshalling the inputs for the underlying [=authenticator operations=], and for returning the results of the latter operations to the [=Web Authentication API=]'s callers.

    The [=[WAC]=] runs on, and is distinct from, a [=[WAC] Device=].

: <dfn>Client Device</dfn>
: <dfn>[WAC] Device</dfn>
:: The hardware device on which the [=[WAC]=] runs, for example a smartphone, a laptop computer or a desktop computer, and the
    operating system running on that hardware.

    The distinctions between a [=[WAC] device=] and a [=client=] are:
    * a single [=client device=] MAY support running multiple [=clients=], i.e., browser implementations,
        which all have access to the same [=authenticators=] available on that [=client device=], and
    * [=platform authenticators=] are bound to a [=client device=] rather than a [=[WAC]=].

    A [=client device=] and a [=client=] together constitute a [=client platform=].

: <dfn>Client Platform</dfn>
:: A [=client device=] and a [=client=] together make up a [=client platform=]. A single hardware device MAY be part of multiple
    distinct [=client platforms=] at different times by running different operating systems and/or [=clients=].

: <dfn>Client-Side</dfn>
:: This refers in general to the combination of the user's [=client platform=], [=authenticators=], and everything gluing
    it all together.

: <dfn>Client-side-resident Public Key Credential Source</dfn>
: <dfn>Resident Credential</dfn>
:: A [=Client-side-resident Public Key Credential Source=], or [=Resident Credential=] for short,
    is a [=public key credential source=] that is discoverable and usable in [=authentication ceremonies=]
    without providing [=credential ID=]s,
    i.e., calling {{CredentialsContainer/get()|navigator.credentials.get()}}
    with an [=list/is empty|empty=] {{PublicKeyCredentialRequestOptions/allowCredentials}} argument.

    As a consequence, a [=resident credential capable=] [=authenticator=] can generate an [=assertion signature=]
    for a [=resident credential=] given only an [=RP ID=],
    which in turn means that the [=public key credential source=]
    is stored in the [=authenticator=] or [=client platform=].
    This is in contrast to a [=server-side-resident public key credential source=],
    which requires that the [=authenticator=] is given both the [=RP ID=] and the [=credential ID=]
    but does not require [=client-side=] storage of the [=public key credential source=].

    See also: [=client-side credential storage modality=].

    Note: [=Resident credentials=] are also usable in [=authentication ceremonies=] where [=credential ID=]s are given,
    i.e., when calling {{CredentialsContainer/get()|navigator.credentials.get()}}
    with a non-[=list/is empty|empty=] {{PublicKeyCredentialRequestOptions/allowCredentials}} argument.

: <dfn>Conforming User Agent</dfn>
:: A user agent implementing, in cooperation with the underlying [=client device=], the [=Web Authentication API=] and algorithms
    given in this specification, and handling communication between [=authenticators=] and [=[RPS]=].

: <dfn>Credential ID</dfn>
:: A probabilistically-unique [=byte sequence=] identifying a [=public key credential source=] and its [=authentication assertions=].

    Credential IDs are generated by [=authenticators=] in two forms:
    1. At least 16 bytes that include at least 100 bits of entropy, or
    1. The [=public key credential source=], without its [=Credential ID=], encrypted so only its [=managing authenticator=] can
        decrypt it. This form allows the [=authenticator=] to be nearly stateless, by having the [=[RP]=] store any necessary
        state.

        Note: [[FIDO-UAF-AUTHNR-CMDS]] includes guidance on encryption techniques under "Security Guidelines".

    [=[RPS]=] do not need to distinguish these two [=Credential ID=] forms.

: <dfn>Credential Key Pair</dfn>
: <dfn>Credential Private Key</dfn>
: <dfn>Credential Public Key</dfn>
: <dfn>User Public Key</dfn>
:: A [=credential key pair=] is a pair of asymmetric cryptographic keys generated by an [=authenticator=]
    and [=scoped=] to a specific [=[WRP]=]. It is the central part of a [=public key credential=].

    A [=credential public key=] is the public key portion of a [=credential key pair=].
    The [=credential public key=] is returned to the [=[RP]=] during a [=registration ceremony=].

    A [=credential private key=] is the private key portion of a [=credential key pair=].
    The [=credential private key=] is bound to a particular [=authenticator=] - its [=managing authenticator=] -
    and is expected to never be exposed to any other party, not even to the owner of the [=authenticator=].

    Note that in the case of [=self
    attestation=], the [=credential key pair=] is also used as the [=attestation key pair=], see [=self attestation=]
    for details.

    Note: The [=credential public key=] is referred to as the [=user public key=] in FIDO UAF [[UAFProtocol]], and in FIDO U2F
    [[FIDO-U2F-Message-Formats]] and some parts of this specification that relate to it.

: <dfn>Credential Properties</dfn>
:: A [=credential property=] is some characteristic property of a [=public key credential source=], such as whether it is a
    [=resident credential=] or a [=non-resident credential=].

: <dfn>Human Palatability</dfn>
:: An identifier that is [=human palatability|human-palatable=] is intended to be rememberable and reproducible by typical human
    users, in contrast to identifiers that are, for example, randomly generated sequences of bits [[EduPersonObjectClassSpec]].

: <dfn>Public Key Credential Source</dfn>
:: A [=credential source=] ([[CREDENTIAL-MANAGEMENT-1]]) used by an [=authenticator=] to generate [=authentication assertions=]. A [=public key credential source=] consists of a [=struct=] with the following [=struct/items=]:

    <dl dfn-for="public key credential source">
        :   <dfn>type</dfn>
        ::  whose value is of {{PublicKeyCredentialType}}, defaulting to {{public-key}}.

        :   <dfn>id</dfn>
        ::  A [=Credential ID=].

        :   <dfn>privateKey</dfn>
        ::  The [=credential private key=].

        :   <dfn>rpId</dfn>
        ::  The [=Relying Party Identifier=], for the [=[RP]=] this [=public key credential source=] is [=scoped=] to.

        :   <dfn>userHandle</dfn>
        ::  The [=user handle=] associated when this [=public key credential source=] was created. This [=struct/item=] is
            nullable.

        :   <dfn>otherUI</dfn>
        ::  OPTIONAL other information used by the [=authenticator=] to inform its UI. For example, this might include the user's
            {{displayName}}.
    </dl>

    The [=authenticatorMakeCredential=] operation creates a [=public key credential source=] [=bound credential|bound=] to a <dfn for="public key
    credential source">managing authenticator</dfn> and returns the [=credential public key=] associated with its [=credential
    private key=]. The [=[RP]=] can use this [=credential public key=] to verify the [=authentication assertions=] created by
    this [=public key credential source=].

: <dfn>Public Key Credential</dfn>
:: Generically, a *credential* is data one entity presents to another in order to *authenticate* the former to the latter
    [[RFC4949]]. The term [=public key credential=] refers to one of: a [=public key credential source=], the
    possibly-[=attestation|attested=] [=credential public key=] corresponding to a [=public key credential source=], or an
    [=authentication assertion=]. Which one is generally determined by context.

    <div class="note">
        Note: This is a [=willful violation=] of [[RFC4949]]. In English, a "credential" is both a) the thing presented to prove
        a statement and b) intended to be used multiple times. It's impossible to achieve both criteria securely with a single
        piece of data in a public key system. [[RFC4949]] chooses to define a credential as the thing that can be used multiple
        times (the public key), while this specification gives "credential" the English term's flexibility. This specification
        uses more specific terms to identify the data related to an [[RFC4949]] credential:

        : "Authentication information" (possibly including a private key)
        :: [=Public key credential source=]
        : "Signed value"
        :: [=Authentication assertion=]
        : [[RFC4949]] "credential"
        :: [=Credential public key=] or [=attestation object=]
    </div>

    At [=registration=] time, the [=authenticator=] creates an asymmetric key pair, and stores its [=credential private
    key|private key portion=] and information from the [=[RP]=] into a [=public key credential source=]. The [=credential public
    key|public key portion=] is returned to the [=[RP]=], who then stores it in conjunction with the present user's account.
    Subsequently, only that [=[RP]=], as identified by its [=RP ID=], is able to employ the [=public key credential=] in
    [=authentication|authentication ceremonies=], via the {{CredentialsContainer/get()}} method. The [=[RP]=] uses its stored
    copy of the [=credential public key=] to verify the resultant [=authentication assertion=].

: <dfn>Rate Limiting</dfn>
:: The process (also known as throttling) by which an authenticator implements controls against brute force attacks by limiting
    the number of consecutive failed authentication attempts within a given period of time. If the limit is reached, the
    authenticator should impose a delay that increases exponentially with each successive attempt, or disable the current
    authentication modality and offer a different [=authentication factor=] if available. [=Rate limiting=] is often implemented as an
    aspect of [=user verification=].

: <dfn>Registration</dfn>
: <dfn>Registration Ceremony</dfn>
:: The [=ceremony=] where a user, a [=[RP]=], and the user's [=client=] (containing at least one
    [=authenticator=]) work in concert to create a [=public key credential=] and associate it with the user's [=[RP]=] account.
    Note that this includes employing a [=test of user presence=] or [=user verification=].

: <dfn>[RP]</dfn>
:: See [=[WRP]=].

: <dfn>Relying Party Identifier</dfn>
: <dfn>RP ID</dfn>
:: A [=valid domain string=] that identifies the [=[WRP]=] on whose behalf a given [=registration=] or
    [=authentication|authentication ceremony=] is being performed. A [=public key credential=] can only be used for
    [=authentication=] with the same entity (as identified by [=RP ID=]) it was registered with.

    By default, the [=RP ID=] for a
    WebAuthn operation is set to the caller's [=environment settings object/origin=]'s [=effective domain=]. This default MAY be
    overridden by the caller, as long as the caller-specified [=RP ID=] value [=is a registrable domain suffix of or is equal
    to=] the caller's [=environment settings object/origin=]'s [=effective domain=]. See also [[#sctn-createCredential]] and
    [[#sctn-getAssertion]].

    <div class="note" id="note-pkcredscope">
        Note: An [=RP ID=] is based on a [=host=]'s [=domain=] name. It does not itself include a [=scheme=] or [=port=], as an [=origin=] does. The [=RP ID=] of a [=public key credential=] determines its <dfn>scope</dfn>. I.e., it <dfn>determines the set of origins on which the public key credential may be exercised</dfn>, as follows:

            - The [=RP ID=] must be equal to the [=determines the set of origins on which the public key credential may be exercised|origin=]'s [=effective domain=], or a [=is a registrable domain suffix of or is equal to|registrable domain suffix=] of the [=determines the set of origins on which the public key credential may be exercised|origin=]'s [=effective domain=].
            - The [=determines the set of origins on which the public key credential may be exercised|origin=]'s [=scheme=] must be `https`.
            - The [=determines the set of origins on which the public key credential may be exercised|origin=]'s [=port=] is unrestricted.

        For example, given a [=[RP]=] whose origin is `https://login.example.com:1337`, then the following [=RP ID=]s are valid: `login.example.com` (default) and `example.com`, but not `m.login.example.com` and not `com`.

        This is done in order to match the behavior of pervasively deployed ambient credentials (e.g., cookies, [[RFC6265]]).
        Please note that this is a greater relaxation of "same-origin" restrictions than what
        [=document.domain=]'s setter provides.

        These restrictions on origin values apply to [=WebAuthn Clients=]. If other specifications mimic the [=Web Authentication API=] to make WebAuthn [=credentials=] usable on other platforms (e.g. native mobile applications), they might have different rules for binding a caller to a [=Relying Party Identifier=]. Such rules are outside the scope of this specification.
    </div>

: <dfn>Server-side-resident Public Key Credential Source</dfn>
: <dfn>Non-Resident Credential</dfn>
:: A [=Server-side-resident Public Key Credential Source=], or [=Non-Resident Credential=] for short,
    is a [=public key credential source=] that cannot be used in an [=authentication ceremony=]
    without providing the [=authenticator=] with the [=credential ID=], e.g.,
    the credential is only usable when its [=credential ID=] is specified in the {{PublicKeyCredentialRequestOptions/allowCredentials}} argument.

    As a consequence, [=client-side=] storage of the [=public key credential source=]
    is not required for a [=non-resident credential=].
    This is in contrast to a [=client-side-resident public key credential source=],
    which does not require the [=credential ID=] to be provided
    but instead requires [=client-side=] storage of the [=public key credential source=].

    See also: [=server-side credential storage modality=].

: <dfn>Test of User Presence</dfn>
:: A [=test of user presence=] is a simple form of [=authorization gesture=] and technical process where a user interacts with
    an [=authenticator=] by (typically) simply touching it (other modalities may also exist), yielding a Boolean result. Note
    that this does not constitute [=user verification=] because a [=test of user presence|user presence test=], by definition,
    is not capable of [=biometric recognition=], nor does it involve the presentation of a shared secret such as a password or
    PIN.

: <dfn>User Consent</dfn>
:: User consent means the user agrees with what they are being asked, i.e., it encompasses reading and understanding prompts.
    An [=authorization gesture=] is a [=ceremony=] component often employed to indicate [=user consent=].

: <dfn>User Handle</dfn>
:: The user handle is specified by a [=[RP]=], as the value of
    <code>{{PublicKeyCredentialCreationOptions/user}}.{{PublicKeyCredentialUserEntity/id}}</code>, and used to [=credentials map|map=] a specific [=public key credential=]
    to a specific user account with the [=[RP]=]. Authenticators in turn [=credentials map|map=] [=RP ID=]s and user handle pairs
    to [=public key credential sources=].

    A user handle is an opaque [=byte sequence=] with a maximum size of 64 bytes, and is not meant to be displayed to the user.

: <dfn>User Verification</dfn>
:: The technical process by which an [=authenticator=] <em>locally authorizes</em> the invocation of the
    [=authenticatorMakeCredential=] and [=authenticatorGetAssertion=] operations. [=User verification=] MAY be instigated
    through various [=authorization gesture=] modalities; for example, through a touch plus pin code, password entry, or
    [=biometric recognition=] (e.g., presenting a fingerprint) [[ISOBiometricVocabulary]]. The intent is to
    distinguish individual users.

    Note that [=user verification=] does not give the [=[RP]=] a concrete identification of the user,
    but when 2 or more ceremonies with [=user verification=] have been done with that [=credential=]
    it expresses that it was the same user that performed all of them.
    The same user might not always be the same natural person, however,
    if multiple natural persons share access to the same [=authenticator=].

    Note: Distinguishing natural persons depends in significant part upon the [=client platform=]'s
    and [=authenticator=]'s capabilities.
    For example, some devices are intended to be used by a single individual,
    yet they may allow multiple natural persons to enroll fingerprints or know the same PIN
    and thus access the same [=[RP]=] account(s) using that device.
    See also [[#sctn-uvi-extension]].

    <div class="note">
        Note: Invocation of the [=authenticatorMakeCredential=] and [=authenticatorGetAssertion=] operations
        implies use of key material managed by the authenticator.

        Also, for security, [=user verification=] and use of [=credential private keys=]
        must all occur within the logical security boundary defining the [=authenticator=].
    </div>

    [=User verification=] procedures MAY implement [=rate limiting=] as a protection against brute force attacks.

: <dfn id=concept-user-present>User Present</dfn>
: <dfn>UP</dfn>
:: Upon successful completion of a [=test of user presence|user presence test=], the user is said to be
    "[=user present|present=]".

: <dfn id=concept-user-verified>User Verified</dfn>
: <dfn>UV</dfn>
:: Upon successful completion of a [=user verification=] process, the user is said to be "[=user verified|verified=]".

: <dfn>[WRP]</dfn>
:: The entity whose <dfn>web application</dfn> utilizes the [[#sctn-api|Web Authentication API]] to [=registration|register=] and
    [=authentication|authenticate=] users.

    A [=[RP]=] implementation typically consists of both some client-side script
    that invokes the [=Web Authentication API=] in the [=client=],
    and a server-side component that executes the [[#sctn-rp-operations|[RP] operations]] and other application logic.
    Communication between the two components MUST use HTTPS or equivalent transport security,
    but is otherwise beyond the scope of this specification.

        Note: While the term [=[RP]=] is also often used in other contexts (e.g., X.509 and OAuth), an entity acting as a [=[RP]=] in one
        context is not necessarily a [=[RP]=] in other contexts. In this specification, the term [=[WRP]=] is often shortened
        to be just [=[RP]=], and explicitly refers to a [=[RP]=] in the WebAuthn context. Note that in any concrete instantiation
        a WebAuthn context may be embedded in a broader overall context, e.g., one based on OAuth.


# <dfn>Web Authentication API</dfn> # {#sctn-api}

This section normatively specifies the API for creating and using [=public key credentials=]. The basic
idea is that the credentials belong to the user and are [=managing authenticator|managed=] by a [=[WAA]=], with which the [=[WRP]=] interacts through the [=client platform=]. [=[RP]=] scripts can (with the [=user consent|user's consent=]) request the
browser to create a new credential for future use by the [=[RP]=]. See <a href="#fig-registration">Figure <span class="figure-num-following"/></a>, below.


<figure id="fig-registration">
    <img src="images/webauthn-registration-flow-01.svg"/>
    <figcaption>Registration Flow</figcaption>
</figure>


Scripts can also request the user’s permission to perform
[=authentication=] operations with an existing credential. See <a href="#fig-authentication">Figure <span class="figure-num-following"/></a>, below.


<figure id="fig-authentication">
    <img src="images/webauthn-authentication-flow-01.svg"/>
    <figcaption>Authentication Flow</figcaption>
</figure>


All such operations are performed in the authenticator and are mediated by
the [=client platform=] on the user's behalf. At no point does the script get access to the credentials themselves; it only
gets information about the credentials in the form of objects.

In addition to the above script interface, the authenticator MAY implement (or come with client software that implements) a user
interface for management. Such an interface MAY be used, for example, to reset the authenticator to a clean state or to inspect
the current state of the authenticator. In other words, such an interface is similar to the user interfaces provided by browsers
for managing user state such as history, saved passwords, and cookies. Authenticator management actions such as credential
deletion are considered to be the responsibility of such a user interface and are deliberately omitted from the API exposed to
scripts.

The security properties of this API are provided by the client and the authenticator working together. The authenticator, which
holds and [=managing authenticator|manages=] credentials, ensures that all operations are [=scoped=] to a particular [=origin=], and cannot be replayed against
a different [=origin=], by incorporating the [=origin=] in its responses. Specifically, as defined in [[#sctn-authenticator-ops]],
the full [=origin=] of the requester is included, and signed over, in the [=attestation object=] produced when a new credential
is created as well as in all assertions produced by WebAuthn credentials.

Additionally, to maintain user privacy and prevent malicious [=[RPS]=] from probing for the presence of [=public key
credentials=] belonging to other [=[RPS]=], each [=public key credential|credential=] is also [=scoped=] to a [=Relying Party
Identifier=], or [=RP ID=]. This [=RP ID=] is provided by the client to the [=authenticator=] for all operations, and the
[=authenticator=] ensures that [=public key credential|credentials=] created by a [=[RP]=] can only be used in operations
requested by the same [=RP ID=]. Separating the [=origin=] from the [=RP ID=] in this way allows the API to be used in cases
where a single [=[RP]=] maintains multiple [=origins=].

The client facilitates these security measures by providing the [=[RP]=]'s [=origin=] and [=RP ID=] to the [=authenticator=] for
each operation. Since this is an integral part of the WebAuthn security model, user agents only expose this API to callers in
[=secure contexts=].
For web contexts in particular,
this only includes those accessed via a secure transport (e.g., TLS) established without errors.

The Web Authentication API is defined by the union of the Web IDL fragments presented in the following sections. A combined IDL
listing is given in the [[#idl-index]].

## <dfn interface>PublicKeyCredential</dfn> Interface ## {#iface-pkcredential}

The {{PublicKeyCredential}} interface inherits from {{Credential}} [[!CREDENTIAL-MANAGEMENT-1]], and contains the attributes
that are returned to the caller when a new credential is created, or a new assertion is requested.

<xmp class="idl">
    [SecureContext, Exposed=Window]
    interface PublicKeyCredential : Credential {
        [SameObject] readonly attribute ArrayBuffer              rawId;
        [SameObject] readonly attribute AuthenticatorResponse    response;
        AuthenticationExtensionsClientOutputs getClientExtensionResults();
    };
</xmp>
<dl dfn-type="attribute" dfn-for="PublicKeyCredential">
    :   {{Credential/id}}
    ::  This attribute is inherited from {{Credential}}, though {{PublicKeyCredential}} overrides {{Credential}}'s getter,
        instead returning the [=base64url encoding=] of the data contained in the object's
        {{PublicKeyCredential/[[identifier]]}} [=internal slot=].

    :   {{PublicKeyCredential/rawId}}
    ::  This attribute returns the {{ArrayBuffer}} contained in the {{PublicKeyCredential/[[identifier]]}} internal slot.

    :   <dfn>response</dfn>
    ::  This attribute contains the [=authenticator=]'s response to the client's request to either create a [=public key
        credential=], or generate an [=authentication assertion=]. If the {{PublicKeyCredential}} is created in response to
        {{CredentialsContainer/create()}}, this attribute's value will be an {{AuthenticatorAttestationResponse}}, otherwise,
        the {{PublicKeyCredential}} was created in response to {{CredentialsContainer/get()}}, and this attribute's value
        will be an {{AuthenticatorAssertionResponse}}.

    :   {{PublicKeyCredential/getClientExtensionResults()}}
    ::  This operation returns the value of {{PublicKeyCredential/[[clientExtensionsResults]]}}, which is a [=map=] containing
        [=extension identifier=] → [=client extension output=] entries produced by the extension's
        [=client extension processing=].

    :   <dfn>\[[type]]</dfn>
    ::  The {{PublicKeyCredential}} [=interface object=]'s {{Credential/[[type]]}} [=internal slot=]'s value is the string
        "`public-key`".

        Note: This is reflected via the {{Credential/type}} attribute getter inherited from {{Credential}}.

    :   <dfn>\[[discovery]]</dfn>
    ::  The {{PublicKeyCredential}} [=interface object=]'s {{Credential/[[discovery]]}} [=internal slot=]'s value is
        "{{Credential/[[discovery]]/remote}}".

    :   <dfn>\[[identifier]]</dfn>
    ::  This [=internal slot=] contains the [=credential ID=], chosen by the authenticator.
        The [=credential ID=] is used to look up credentials for use, and is therefore expected to be globally unique
        with high probability across all credentials of the same type, across all authenticators.

        Note: This API does not constrain
        the format or length of this identifier, except that it MUST be sufficient for the [=authenticator=] to uniquely select a key.
        For example, an authenticator without on-board storage may create identifiers containing a [=credential private key=]
        wrapped with a symmetric key that is burned into the authenticator.

    :   <dfn>\[[clientExtensionsResults]]</dfn>
    ::  This [=internal slot=] contains the results of processing client extensions requested by the [=[RP]=] upon the
        [=[RP]=]'s invocation of either {{CredentialsContainer/create()|navigator.credentials.create()}} or
        {{CredentialsContainer/get()|navigator.credentials.get()}}.
</dl>

{{PublicKeyCredential}}'s [=interface object=] inherits {{Credential}}'s implementation of
{{Credential/[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)}}, and defines its own
implementation of {{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)}}, {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)}}, and
{{Credential/[[Store]](credential, sameOriginWithAncestors)}}.


### `CredentialCreationOptions` Dictionary Extension ### {#sctn-credentialcreationoptions-extension}

To support registration via {{CredentialsContainer/create()|navigator.credentials.create()}}, this document extends
the {{CredentialCreationOptions}} dictionary as follows:

<xmp class="idl">
    partial dictionary CredentialCreationOptions {
        PublicKeyCredentialCreationOptions      publicKey;
    };
</xmp>

### `CredentialRequestOptions` Dictionary Extension ### {#sctn-credentialrequestoptions-extension}

To support obtaining assertions via {{CredentialsContainer/get()|navigator.credentials.get()}}, this document extends the
{{CredentialRequestOptions}} dictionary as follows:

<xmp class="idl">
    partial dictionary CredentialRequestOptions {
        PublicKeyCredentialRequestOptions      publicKey;
    };
</xmp>


### Create a New Credential - PublicKeyCredential's `[[Create]](origin, options, sameOriginWithAncestors)` Method ### {#sctn-createCredential}

<div link-for-hint="PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)">
{{PublicKeyCredential}}'s [=interface object=]'s implementation of the <dfn for="PublicKeyCredential" method>\[[Create]](origin,
options, sameOriginWithAncestors)</dfn> [=internal method=] [[!CREDENTIAL-MANAGEMENT-1]] allows
[=[WRP]=] scripts to call {{CredentialsContainer/create()|navigator.credentials.create()}} to request the creation of a new
[=public key credential source=], [=bound credential|bound=] to an [=authenticator=]. This
{{CredentialsContainer/create()|navigator.credentials.create()}} operation can be aborted by leveraging the {{AbortController}};
see [[dom#abortcontroller-api-integration]] for detailed instructions.


This [=internal method=] accepts three arguments:

<dl dfn-type="argument" dfn-for="PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)">

    :   <dfn>origin</dfn>
    ::  This argument is the [=relevant settings object=]'s [=environment settings object/origin=], as determined by the
        calling {{CredentialsContainer/create()}} implementation.

    :   <dfn>options</dfn>
    ::  This argument is a {{CredentialCreationOptions}} object whose
        <code>|options|.{{CredentialCreationOptions/publicKey}}</code> member contains a {{PublicKeyCredentialCreationOptions}}
        object specifying the desired attributes of the to-be-created [=public key credential=].

    :   <dfn>sameOriginWithAncestors</dfn>
    ::  This argument is a Boolean value which is [TRUE] if and only if the caller's [=environment settings object=] is
        [=same-origin with its ancestors=]. It is [FALSE] if caller is cross-origin.

        Note: Invocation of this [=internal method=] indicates that it was allowed by
        [=feature policy=], which is evaluated at the [[!CREDENTIAL-MANAGEMENT-1]] level.
        See [[#sctn-feature-policy]].

</dl>

Note: <strong>This algorithm is synchronous:</strong> the {{Promise}} resolution/rejection is handled by
{{CredentialsContainer/create()|navigator.credentials.create()}}.

Note: All {{BufferSource}} objects used in this algorithm must be snapshotted when the algorithm begins, to
avoid potential synchronization issues. The algorithm implementations should [=get a copy of the bytes held
by the buffer source=] and use that copy for relevant portions of the algorithm.

When this method is invoked, the user agent MUST execute the following algorithm:

1. Assert: <code>|options|.{{CredentialCreationOptions/publicKey}}</code> is [=present=].

1. Let |options| be the value of <code>|options|.{{CredentialCreationOptions/publicKey}}</code>.

1. If the {{PublicKeyCredentialCreationOptions/timeout}} member of |options| is [=present=], check if its value lies within a
    reasonable range as defined by the [=client=] and if not, correct it to the closest value lying within that range. Set a timer
    |lifetimeTimer| to this adjusted value. If the {{PublicKeyCredentialCreationOptions/timeout}} member of |options| is [=present|not
    present=], then set |lifetimeTimer| to a [=client=]-specific default.

        Recommended ranges and defaults for the {{PublicKeyCredentialCreationOptions/timeout}} member of |options| are as follows.
          If <code>|options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{AuthenticatorSelectionCriteria/userVerification}}</code>
            <dl class="switch">
                :   is set to {{UserVerificationRequirement/discouraged}}
                ::  Recommended range: 30000 milliseconds to 180000 milliseconds.
                ::  Recommended default value: 120000 milliseconds (2 minutes).

                :   is set to {{UserVerificationRequirement/required}} or {{UserVerificationRequirement/preferred}}
                ::  Recommended range: 30000 milliseconds to 600000 milliseconds.
                ::  Recommended default value: 300000 milliseconds (5 minutes).
            </dl>

        Note: The user agent should take cognitive guidelines into considerations regarding timeout for users with special needs.

1. Let |callerOrigin| be {{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)/origin}}. If |callerOrigin| is an [=opaque origin=], return a {{DOMException}} whose name is
    "{{NotAllowedError}}", and terminate this algorithm.

1. Let |effectiveDomain| be the |callerOrigin|'s [=effective domain=].
    If [=effective domain=] is not a [=valid domain=], then return a
    {{DOMException}} whose name is "{{SecurityError}}" and terminate this algorithm.

    Note: An [=effective domain=] may resolve to a [=host=], which can be represented in various manners,
        such as [=domain=], [=ipv4 address=], [=ipv6 address=], [=opaque host=], or [=empty host=].
        Only the [=domain=] format of [=host=] is allowed here. This is for simplification and also
        is in recognition of various issues with using direct IP address identification in concert
        with PKI-based security.

<!-- Note: this next step is actually a top-level step, but bikeshed wanted it indented this much in order to render it as
a numbered step. If outdented, it (today) is rendered as a bullet in the midst of a numbered list :-/
-->
    <li id='CreateCred-DetermineRpId'>

        If <code>|options|.{{PublicKeyCredentialCreationOptions/rp}}.{{PublicKeyCredentialRpEntity/id}}</code>
            <dl class="switch">

                :   Is [=present=]
                ::  If <code>|options|.{{PublicKeyCredentialCreationOptions/rp}}.{{PublicKeyCredentialRpEntity/id}}</code> [=is not a
                    registrable domain suffix of and is not equal to=] |effectiveDomain|, return a {{DOMException}} whose name
                    is "{{SecurityError}}", and terminate this algorithm.

                :   Is [=present|not present=]
                ::  Set <code>|options|.{{PublicKeyCredentialCreationOptions/rp}}.{{PublicKeyCredentialRpEntity/id}}</code> to
                    |effectiveDomain|.
            </dl>

        Note: <code>|options|.{{PublicKeyCredentialCreationOptions/rp}}.{{PublicKeyCredentialRpEntity/id}}</code> represents the
            caller's [=RP ID=]. The [=RP ID=] defaults to being the caller's [=environment settings object/origin=]'s
            [=effective domain=] unless the caller has explicitly set
            <code>|options|.{{PublicKeyCredentialCreationOptions/rp}}.{{PublicKeyCredentialRpEntity/id}}</code> when calling
            {{CredentialsContainer/create()}}.
    </li>

1. Let |credTypesAndPubKeyAlgs| be a new [=list=] whose [=list/items=] are pairs of {{PublicKeyCredentialType}} and
    a {{COSEAlgorithmIdentifier}}.

1. [=list/For each=] |current| of <code>|options|.{{PublicKeyCredentialCreationOptions/pubKeyCredParams}}</code>:

    1. If <code>|current|.{{PublicKeyCredentialParameters/type}}</code> does not contain a {{PublicKeyCredentialType}} supported
        by this implementation, then [=continue=].
    1. Let |alg| be <code>|current|.{{PublicKeyCredentialParameters/alg}}</code>.
    1. [=list/Append=] the pair of <code>|current|.{{PublicKeyCredentialParameters/type}}</code> and |alg| to
        |credTypesAndPubKeyAlgs|.

1. If |credTypesAndPubKeyAlgs| [=list/is empty=] and <code>|options|.{{PublicKeyCredentialCreationOptions/pubKeyCredParams}}</code>
    [=list/is not empty=], return a {{DOMException}} whose name is "{{NotSupportedError}}", and terminate this algorithm.

1. Let |clientExtensions| be a new [=map=] and let |authenticatorExtensions| be a new [=map=].

1. If the {{PublicKeyCredentialCreationOptions/extensions}} member of |options| is [=present=], then [=map/for each=]
    |extensionId| → |clientExtensionInput| of <code>|options|.{{PublicKeyCredentialCreationOptions/extensions}}</code>:
    1. If |extensionId| is not supported by this [=client platform=] or is not a [=registration extension=], then [=continue=].

    1. [=map/Set=] |clientExtensions|[|extensionId|] to |clientExtensionInput|.

    1. If |extensionId| is not an [=authenticator extension=], then [=continue=].

    1. Let |authenticatorExtensionInput| be the ([=CBOR=]) result of running |extensionId|'s [=client extension processing=]
        algorithm on |clientExtensionInput|. If the algorithm returned an error, [=continue=].

    1. [=map/Set=] |authenticatorExtensions|[|extensionId|] to the [=base64url encoding=] of |authenticatorExtensionInput|.

1. Let |collectedClientData| be a new {{CollectedClientData}} instance whose fields are:
    : {{CollectedClientData/type}}
    :: The string "webauthn.create".
    : {{CollectedClientData/challenge}}
    :: The [=base64url encoding=] of |options|.{{PublicKeyCredentialCreationOptions/challenge}}.
    : {{CollectedClientData/origin}}
    :: The [=ascii serialization of an origin|serialization of=] |callerOrigin|.
    : {{CollectedClientData/crossOrigin}}
    :: The inverse of the value of the
        {{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)/sameOriginWithAncestors}}
        argument passed to this [=internal method=].
    : {{CollectedClientData/tokenBinding}}
    :: The status of [=Token Binding=] between the client and the |callerOrigin|, as well as the [=Token Binding ID=] associated with |callerOrigin|, if one is available.

1. Let |clientDataJSON| be the [=JSON-serialized client data=] constructed from |collectedClientData|.

1. Let |clientDataHash| be the [=hash of the serialized client data=] represented by |clientDataJSON|.

1. If the <code>|options|.{{CredentialCreationOptions/signal}}</code> is [=present=] and its
    [=AbortSignal/aborted flag=] is set to [TRUE], return a {{DOMException}} whose name is "{{AbortError}}"
    and terminate this algorithm.

1. Let |issuedRequests| be a new [=ordered set=].

1. Let |authenticators| represent a value which at any given instant is a [=set=] of [=client platform=]-specific handles, where each
    [=set/item=] identifies an [=authenticator=] presently available on this [=client platform=] at that instant.

    Note: What qualifies an [=authenticator=] as "available" is intentionally unspecified; this is meant to represent how
    [=authenticators=] can be <a href="https://en.wikipedia.org/w/index.php?title=Hot_plug">hot-plugged</a> into (e.g., via USB)
    or discovered (e.g., via NFC or Bluetooth) by the [=client=] by various mechanisms, or permanently built into the [=client=].

1. Start |lifetimeTimer|.

1. [=While=] |lifetimeTimer| has not expired, perform the following actions depending upon |lifetimeTimer|,
    and the state and response [=set/for each=] |authenticator| in |authenticators|:
    <dl class="switch">
        :   If |lifetimeTimer| expires,
        ::  [=set/For each=] |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on |authenticator|
            and [=set/remove=] |authenticator| from |issuedRequests|.

        :   If the user exercises a user agent user-interface option to cancel the process,
        ::  [=set/For each=] |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on |authenticator|
            and [=set/remove=] |authenticator| from |issuedRequests|. Return a {{DOMException}} whose name is "{{NotAllowedError}}".

        :   If the <code>|options|.{{CredentialCreationOptions/signal}}</code> is [=present=] and its
            [=AbortSignal/aborted flag=] is set to [TRUE],
        ::  [=set/For each=] |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=]
            operation on |authenticator| and [=set/remove=] |authenticator| from |issuedRequests|. Then return a {{DOMException}}
            whose name is "{{AbortError}}" and terminate this algorithm.

        :   If an |authenticator| becomes available on this [=client device=],
        ::  Note:  This includes the case where an |authenticator| was available upon |lifetimeTimer| initiation.

            1. If <code>|options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}</code> is [=present=]:

                  1. If <code>|options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{authenticatorAttachment}}</code> is
                    [=present|present=] and its value is not equal to |authenticator|'s [=authenticator attachment modality=], [=iteration/continue=].

                  1. If <code>|options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{residentKey}}</code>

                      <dl class="switch">
                          :   is present and set to {{ResidentKeyRequirement/required}}
                          ::  If the |authenticator| is not capable of storing a [=client-side-resident public key credential
                              source=], [=iteration/continue=].

                          :   is present and set to {{ResidentKeyRequirement/preferred}} or {{ResidentKeyRequirement/discouraged}}
                          ::  No effect.

                          :   is [=not present=]
                          ::  if <code>|options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{requireResidentKey}}</code>
                              is set to [TRUE] and the |authenticator| is not capable of storing a [=client-side-resident public
                              key credential source=], [=iteration/continue=].
                      </dl>

                  1. If <code>|options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{AuthenticatorSelectionCriteria/userVerification}}</code> is
                    set to {{UserVerificationRequirement/required}} and the |authenticator| is not capable of performing [=user
                    verification=], [=iteration/continue=].

            1. Let |requireResidentKey| be the <dfn>effective resident key requirement for credential creation</dfn>, a Boolean value, as follows:

                If <code>|options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{residentKey}}</code>

                    <dl class="switch">

                        :   is present and set to {{ResidentKeyRequirement/required}}
                        ::  Let |requireResidentKey| be [TRUE].

                        :   is present and set to {{ResidentKeyRequirement/preferred}}
                        ::  If the |authenticator|

                            <dl class="switch">
                                :   is capable of [=client-side credential storage modality=]
                                ::  Let |requireResidentKey| be [TRUE].

                                :   is not capable of [=client-side credential storage modality=], or if the [=client=] cannot determine authenticator capability,
                                ::  Let |requireResidentKey| be [FALSE].
                            </dl>

                        :   is present and set to {{ResidentKeyRequirement/discouraged}}
                        ::  Let |requireResidentKey| be [FALSE].

                        :   is [=not present=]
                        ::  Let |requireResidentKey| be the value of <code>|options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{requireResidentKey}}</code>.

                    </dl>

            1. Let |userVerification| be the <dfn>effective user verification requirement for credential creation</dfn>, a Boolean value,
                as follows. If
                <code>|options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{AuthenticatorSelectionCriteria/userVerification}}</code>

                    <dl class="switch">

                        :   is set to {{UserVerificationRequirement/required}}
                        ::  Let |userVerification| be [TRUE].

                        :   is set to {{UserVerificationRequirement/preferred}}
                        ::  If the |authenticator|

                            <dl class="switch">
                                :   is capable of [=user verification=]
                                ::  Let |userVerification| be [TRUE].

                                :   is not capable of [=user verification=]
                                ::  Let |userVerification| be [FALSE].
                            </dl>

                        :   is set to {{UserVerificationRequirement/discouraged}}
                        ::  Let |userVerification| be [FALSE].

                    </dl>

            1. Let |excludeCredentialDescriptorList| be a new [=list=].

            1. [=list/For each=] credential descriptor |C| in <code>|options|.{{PublicKeyCredentialCreationOptions/excludeCredentials}}</code>:
                1. If <code>|C|.{{transports}}</code> [=list/is not empty=], and |authenticator| is connected over a transport not
                    mentioned in <code>|C|.{{transports}}</code>, the client MAY [=continue=].
                1. Otherwise, [=list/Append=] |C| to |excludeCredentialDescriptorList|.

<!-- Note: this next step is actually a top-level step, but bikeshed wanted it indented this much in order to render it as
a numbered step. If outdented, it (today) is rendered either as a bullet in the midst of a numbered list or is mis-numabered :-/
-->
        	    <li id='CreateCred-InvokeAuthnrMakeCred'>

        		<!-- @@EDITOR-ANCHOR-01A: KEEP THIS LIST SYNC'D WITH THE LIST UP AT @@EDITOR-ANCHOR-01B -->
        		Invoke the [=authenticatorMakeCredential=] operation on |authenticator| with
                	    |clientDataHash|,
                	    <code>|options|.{{PublicKeyCredentialCreationOptions/rp}}</code>, <code>|options|.{{PublicKeyCredentialCreationOptions/user}}</code>,
                	    |requireResidentKey|,
                	    |userVerification|,
                	    |credTypesAndPubKeyAlgs|,
                	    |excludeCredentialDescriptorList|,
                	    and |authenticatorExtensions| as parameters.

        	    </li>

            1. [=set/Append=] |authenticator| to |issuedRequests|.

        :   If an |authenticator| ceases to be available on this [=client device=],
        ::  [=set/Remove=] |authenticator| from |issuedRequests|.

        :   If any |authenticator| returns a status indicating that the user cancelled the operation,
        ::  1. [=set/Remove=] |authenticator| from |issuedRequests|.
            1. [=set/For each=] remaining |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on
                |authenticator| and [=set/remove=] it from |issuedRequests|.

                Note: [=Authenticators=] may return an indication of "the user cancelled the entire operation".
                How a user agent manifests this state to users is unspecified.

        :   If any |authenticator| returns an error status equivalent to "{{InvalidStateError}}",
        ::  1. [=set/Remove=] |authenticator| from |issuedRequests|.
            1. [=set/For each=] remaining |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on
                |authenticator| and [=set/remove=] it from |issuedRequests|.
            1. Return a {{DOMException}} whose name is "{{InvalidStateError}}" and terminate this algorithm.

            Note: This error status is handled separately because the |authenticator| returns it only if
            |excludeCredentialDescriptorList| identifies a credential [=bound credential|bound=] to the |authenticator| and the user has [=user
            consent|consented=] to the operation. Given this explicit consent, it is acceptable for this case to be
            distinguishable to the [=[RP]=].

        :   If any |authenticator| returns an error status not equivalent to "{{InvalidStateError}}",
        ::  [=set/Remove=] |authenticator| from |issuedRequests|.

            Note: This case does not imply [=user consent=] for the operation, so details about the error are hidden from the
            [=[RP]=] in order to prevent leak of potentially identifying information. See [[#sctn-make-credential-privacy]] for
            details.

        :   If any |authenticator| indicates success,
        ::  1.  [=set/Remove=] |authenticator| from |issuedRequests|.

            1.  Let |credentialCreationData| be a [=struct=] whose [=items=] are:

                :   <code><dfn for="credentialCreationData">attestationObjectResult</dfn></code>
                ::  whose value is the bytes returned from the successful [=authenticatorMakeCredential=] operation.

                    Note: this value is <code>attObj</code>, as defined in [[#sctn-generating-an-attestation-object]].

                :   <code><dfn for="credentialCreationData">clientDataJSONResult</dfn></code>
                ::  whose value is the bytes of |clientDataJSON|.

                :   <code><dfn for="credentialCreationData">attestationConveyancePreferenceOption</dfn></code>
                ::  whose value is the value of |options|.{{PublicKeyCredentialCreationOptions/attestation}}.

                :   <code><dfn for="credentialCreationData">clientExtensionResults</dfn></code>
                ::  whose value is an {{AuthenticationExtensionsClientOutputs}} object containing [=extension identifier=] →
                    [=client extension output=] entries. The entries are created by running each extension's
                    [=client extension processing=] algorithm to create the [=client extension outputs=], for each
                    [=client extension=] in <code>{{AuthenticatorResponse/clientDataJSON}}.clientExtensions</code>.


            1.  Let |constructCredentialAlg| be an algorithm that takes a [=global object=]
                |global|, and whose steps are:

                1.  If <code>|credentialCreationData|.[=attestationConveyancePreferenceOption=]</code>'s value is
                    <dl class="switch">
                        :   "none"
                        ::  Replace potentially uniquely identifying information with non-identifying versions of the
                            same:
                               1. If the [=AAGUID=] in the [=attested credential data=] is 16 zero bytes, <code>|credentialCreationData|.[=attestationObjectResult=].fmt</code> is "packed", and "x5c" & "ecdaaKeyId" are both absent from <code>|credentialCreationData|.[=attestationObjectResult=]</code>, then [=self attestation=] is being used and no further action is needed.
                               1. Otherwise
                                  1. Replace the [=AAGUID=] in the [=attested credential data=] with 16 zero bytes.
                                  1. Set the value of <code>|credentialCreationData|.[=attestationObjectResult=].fmt</code> to "none", and set the value of <code>|credentialCreationData|.[=attestationObjectResult=].attStmt</code> to be an empty [=CBOR=] map. (See [[#sctn-none-attestation]] and [[#sctn-generating-an-attestation-object]]).

                        :   "indirect"
                        ::  The client MAY replace the [=AAGUID=] and [=attestation statement=] with a more privacy-friendly
                            and/or more easily verifiable version of the same data (for example, by employing an [=Anonymization CA=]).

                        :   "direct"
                        ::  Convey the [=authenticator=]'s [=AAGUID=] and [=attestation statement=], unaltered, to the [=[RP]=].
                    </dl>

                1.  Let |attestationObject| be a new {{ArrayBuffer}}, created using |global|'s [=%ArrayBuffer%=], containing the
                    bytes of <code>|credentialCreationData|.[=attestationObjectResult=]</code>'s value.

                1.  Let |id| be <code>|attestationObject|.authData.[=attestedCredentialData=].[=credentialId=]</code>.

                1.  Let |pubKeyCred| be a new {{PublicKeyCredential}} object associated with |global| whose fields are:

                    :   {{PublicKeyCredential/[[identifier]]}}
                    ::  |id|

                    :   {{PublicKeyCredential/response}}
                    ::  A new {{AuthenticatorAttestationResponse}} object associated with |global| whose fields are:

                        :   {{AuthenticatorResponse/clientDataJSON}}
                        ::  A new {{ArrayBuffer}}, created using |global|'s [=%ArrayBuffer%=], containing the bytes of
                            <code>|credentialCreationData|.[=credentialCreationData/clientDataJSONResult=]</code>.

                        :   {{AuthenticatorAttestationResponse/attestationObject}}
                        ::  |attestationObject|

                        :   {{AuthenticatorAttestationResponse/[[transports]]}}
                        ::  A sequence of zero or more unique {{DOMString}}s, in lexicographical order, that the |authenticator| is believed to support. The values SHOULD be members of {{AuthenticatorTransport}}.

                            If a user agent does not wish to divulge this information it MAY substitute an arbitrary sequence designed to preserve privacy. This sequence MUST still be valid, i.e. lexicographically sorted and free of duplicates. For example, it may use the empty sequence. Either way, in this case the user agent takes the risk that [=[RP]=] behavior may be suboptimal.

                            If the user agent does not have any transport information, it SHOULD set this field to the empty sequence.

                            Note: How user agents discover transports supported by a given [=authenticator=] is outside the scope of this specification, but may include information from an [=attestation certificate=] (for example [[FIDO-Transports-Ext]]), metadata communicated in an [=authenticator=] protocol such as CTAP2, or special-case knowledge about a [=platform authenticator=].

                    :   {{PublicKeyCredential/[[clientExtensionsResults]]}}
                    ::  A new {{ArrayBuffer}}, created using |global|'s [=%ArrayBuffer%=], containing the bytes of
                        <code>|credentialCreationData|.[=credentialCreationData/clientExtensionResults=]</code>.

                1.  Return |pubKeyCred|.

            1. [=set/For each=] remaining |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on
                |authenticator| and [=set/remove=] it from |issuedRequests|.

            1. Return |constructCredentialAlg| and terminate this algorithm.

    </dl>

1. Return a {{DOMException}} whose name is "{{NotAllowedError}}". In order to prevent information leak that could identify the
    user without [=user consent|consent=], this step MUST NOT be executed before |lifetimeTimer| has expired. See
    [[#sctn-make-credential-privacy]] for details.

During the above process, the user agent SHOULD show some UI to the user to guide them in the process of selecting and
authorizing an authenticator.
</div>


### Use an Existing Credential to Make an Assertion - PublicKeyCredential's `[[Get]](options)` Method ### {#sctn-getAssertion}

[=[WRPS]=] call <code><a idl for="CredentialsContainer" lt="get()">navigator.credentials.get({publicKey:..., ...})</a></code> to
discover and use an existing [=public key credential=], with the [=user consent|user's consent=]. [=[RP]=] script optionally specifies some criteria
to indicate what [=credential sources=] are acceptable to it. The [=client platform=] locates [=credential sources=]
matching the specified criteria, and guides the user to pick one that the script will be allowed to use. The user may choose to
decline the entire interaction even if a [=credential source=] is present, for example to maintain privacy. If the user picks a
[=credential source=], the user agent then uses
[[#sctn-op-get-assertion]] to sign a [=[RP]=]-provided challenge and other collected data into an assertion, which is used as a
[=credential=].

The {{CredentialsContainer/get()}} implementation [[!CREDENTIAL-MANAGEMENT-1]] calls
<code>PublicKeyCredential.{{PublicKeyCredential/[[CollectFromCredentialStore]]()}}</code> to collect any [=credentials=] that
should be available without [=user mediation=] (roughly, this specification's [=authorization gesture=]), and if it does not find
exactly one of those, it then calls <code>PublicKeyCredential.{{PublicKeyCredential/[[DiscoverFromExternalSource]]()}}</code> to have
the user select a [=credential source=].

Since this specification requires an [=authorization gesture=] to create any [=credentials=], the <code>PublicKeyCredential.<dfn
for="PublicKeyCredential" method>\[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)</dfn></code> [=internal method=] inherits the default behavior of
{{Credential/[[CollectFromCredentialStore]]()|Credential.[[CollectFromCredentialStore]]()}}, of returning an empty set.

This
{{CredentialsContainer/get()|navigator.credentials.get()}} operation can be aborted by leveraging the {{AbortController}};
see [[dom#abortcontroller-api-integration]] for detailed instructions.

#### PublicKeyCredential's <code><dfn for="PublicKeyCredential" method>\[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)</dfn></code> Method #### {#sctn-discover-from-external-source}

<div link-for-hint="PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)">

This [=internal method=] accepts three arguments:

<dl dfn-type="argument" dfn-for="PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)">

    :   <dfn>origin</dfn>
    ::  This argument is the [=relevant settings object=]'s [=environment settings object/origin=], as determined by the
        calling {{CredentialsContainer/get()}} implementation, i.e., {{CredentialsContainer}}'s <a abstract-op>Request a `Credential`</a> abstract operation.

    :   <dfn>options</dfn>
    ::  This argument is a {{CredentialRequestOptions}} object whose
        <code>|options|.{{CredentialRequestOptions/publicKey}}</code> member contains a {{PublicKeyCredentialRequestOptions}}
        object specifying the desired attributes of the [=public key credential=] to discover.

    :   <dfn>sameOriginWithAncestors</dfn>
    ::  This argument is a Boolean value which is [TRUE] if and only if the caller's [=environment settings object=] is
        [=same-origin with its ancestors=]. It is [FALSE] if caller is cross-origin.

        Note: Invocation of this [=internal method=] indicates that it was allowed by
        [=feature policy=], which is evaluated at the [[!CREDENTIAL-MANAGEMENT-1]] level.
        See [[#sctn-feature-policy]].
</dl>

Note: <strong>This algorithm is synchronous:</strong> the {{Promise}} resolution/rejection is handled by
{{CredentialsContainer/get()|navigator.credentials.get()}}.

Note: All {{BufferSource}} objects used in this algorithm must be snapshotted when the algorithm begins, to
avoid potential synchronization issues. The algorithm implementations should [=get a copy of the bytes held
by the buffer source=] and use that copy for relevant portions of the algorithm.

When this method is invoked, the user agent MUST execute the following algorithm:

1. Assert: <code>|options|.{{CredentialRequestOptions/publicKey}}</code> is [=present=].

1. Let |options| be the value of <code>|options|.{{CredentialRequestOptions/publicKey}}</code>.

1. If the {{PublicKeyCredentialRequestOptions/timeout}} member of |options| is [=present=], check if its value lies
    within a reasonable range as defined by the [=client=] and if not, correct it to the closest value lying within that range.
    Set a timer |lifetimeTimer| to this adjusted value. If the {{PublicKeyCredentialRequestOptions/timeout}} member of
    |options| is [=present|not present=], then set |lifetimeTimer| to a [=client=]-specific default.

        Recommended ranges and defaults for the {{PublicKeyCredentialRequestOptions/timeout}} member of |options| are as follows.
          If <code>|options|.{{PublicKeyCredentialRequestOptions/userVerification}}</code>
            <dl class="switch">
                :   is set to {{UserVerificationRequirement/discouraged}}
                ::  Recommended range: 30000 milliseconds to 180000 milliseconds.
                ::  Recommended default value: 120000 milliseconds (2 minutes).

                :   is set to {{UserVerificationRequirement/required}} or {{UserVerificationRequirement/preferred}}
                ::  Recommended range: 30000 milliseconds to 600000 milliseconds.
                ::  Recommended default value: 300000 milliseconds (5 minutes).
            </dl>

        Note: The user agent should take cognitive guidelines into considerations regarding timeout for users with special needs.

1. Let |callerOrigin| be {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)/origin}}. If |callerOrigin| is
    an [=opaque origin=], return a {{DOMException}} whose name is "{{NotAllowedError}}", and terminate this algorithm.

1. Let |effectiveDomain| be the |callerOrigin|'s [=effective domain=].
    If [=effective domain=] is not a [=valid domain=], then return a
    {{DOMException}} whose name is "{{SecurityError}}" and terminate this algorithm.

    Note: An [=effective domain=] may resolve to a [=host=], which can be represented in various manners,
        such as [=domain=], [=ipv4 address=], [=ipv6 address=], [=opaque host=], or [=empty host=].
        Only the [=domain=] format of [=host=] is allowed here. This is for simplification and also is
        in recognition of various issues with using direct IP address identification in concert with
        PKI-based security.

        <li id='GetAssn-DetermineRpId'>
            If |options|.{{PublicKeyCredentialRequestOptions/rpId}} is [=present|not present=], then set |rpId| to
                |effectiveDomain|.

                Otherwise:

                1. If |options|.{{PublicKeyCredentialRequestOptions/rpId}} [=is not a registrable domain suffix of and is not
                    equal to=] |effectiveDomain|, return a {{DOMException}} whose name is "{{SecurityError}}", and terminate
                    this algorithm.

                1. Set |rpId| to |options|.{{PublicKeyCredentialRequestOptions/rpId}}.

                    Note: |rpId| represents the caller's [=RP ID=]. The [=RP ID=] defaults to being the caller's [=environment
                    settings object/origin=]'s [=effective domain=] unless the caller has explicitly set
                    |options|.{{PublicKeyCredentialRequestOptions/rpId}} when calling {{CredentialsContainer/get()}}.
        </li>

1. Let |clientExtensions| be a new [=map=] and let |authenticatorExtensions| be a new [=map=].

1. If the {{PublicKeyCredentialRequestOptions/extensions}} member of |options| is [=present=], then [=map/for each=]
    |extensionId| → |clientExtensionInput| of <code>|options|.{{PublicKeyCredentialRequestOptions/extensions}}</code>:
    1. If |extensionId| is not supported by this [=client platform=] or is not an [=authentication extension=], then [=continue=].

    1. [=map/Set=] |clientExtensions|[|extensionId|] to |clientExtensionInput|.

    1. If |extensionId| is not an [=authenticator extension=], then [=continue=].

    1. Let |authenticatorExtensionInput| be the ([=CBOR=]) result of running |extensionId|'s [=client extension processing=]
        algorithm on |clientExtensionInput|. If the algorithm returned an error, [=continue=].

    1. [=map/Set=] |authenticatorExtensions|[|extensionId|] to the [=base64url encoding=] of |authenticatorExtensionInput|.

1. Let |collectedClientData| be a new {{CollectedClientData}} instance whose fields are:
    : {{CollectedClientData/type}}
    :: The string "webauthn.get".
    : {{CollectedClientData/challenge}}
    :: The [=base64url encoding=] of |options|.{{PublicKeyCredentialRequestOptions/challenge}}
    : {{CollectedClientData/origin}}
    :: The [=ascii serialization of an origin|serialization of=] |callerOrigin|.
    : {{CollectedClientData/crossOrigin}}
    :: The inverse of the value of the
        {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)/sameOriginWithAncestors}}
        argument passed to this [=internal method=].
    : {{CollectedClientData/tokenBinding}}
    :: The status of [=Token Binding=] between the client and the |callerOrigin|, as well as the [=Token Binding ID=] associated with |callerOrigin|, if one is available.

1. Let |clientDataJSON| be the [=JSON-serialized client data=] constructed from |collectedClientData|.

1. Let |clientDataHash| be the [=hash of the serialized client data=] represented by |clientDataJSON|.

1. If the <code>|options|.{{CredentialRequestOptions/signal}}</code> is [=present=] and its
    [=AbortSignal/aborted flag=] is set to [TRUE], return a {{DOMException}} whose name is "{{AbortError}}"
    and terminate this algorithm.

1. Let |issuedRequests| be a new [=ordered set=].

1. Let |savedCredentialIds| be a new [=map=].

1. Let |authenticators| represent a value which at any given instant is a [=set=] of [=client platform=]-specific handles, where each
    [=set/item=] identifies an [=authenticator=] presently available on this [=client platform=] at that instant.

    Note: What qualifies an [=authenticator=] as "available" is intentionally unspecified; this is meant to represent how
    [=authenticators=] can be <a href="https://en.wikipedia.org/w/index.php?title=Hot_plug">hot-plugged</a> into (e.g., via USB)
    or discovered (e.g., via NFC or Bluetooth) by the [=client=] by various mechanisms, or permanently built into the [=client=].

1. Start |lifetimeTimer|.

1. [=While=] |lifetimeTimer| has not expired, perform the following actions depending upon |lifetimeTimer|,
    and the state and response [=set/for each=] |authenticator| in |authenticators|:

    <dl class="switch">

        :   If |lifetimeTimer| expires,
        ::  [=set/For each=] |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on
            |authenticator| and [=set/remove=] |authenticator| from |issuedRequests|.

        :   If the user exercises a user agent user-interface option to cancel the process,
        ::  [=set/For each=] |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on |authenticator|
            and [=set/remove=] |authenticator| from |issuedRequests|. Return a {{DOMException}} whose name is "{{NotAllowedError}}".

        :   If the {{CredentialRequestOptions/signal}} member is [=present=] and the [=AbortSignal/aborted flag=] is set to
            [TRUE],
        ::  [=set/For each=] |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation on |authenticator|
            and [=set/remove=] |authenticator| from |issuedRequests|. Then
            return a {{DOMException}} whose name is "{{AbortError}}" and terminate this algorithm.

        :   If |issuedRequests| is empty, <code>|options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}</code> is not empty, and no |authenticator| will become available for any [=public key credentials=] therein,
        ::  Indicate to the user that no eligible credential could be found. When the user acknowledges the dialog, return a {{DOMException}} whose name is "{{NotAllowedError}}".

            Note: One way a [=client platform=] can determine that no |authenticator| will become available is by examining the <code>{{transports}}</code> members of the present <code>{{PublicKeyCredentialDescriptor}}</code> [=list/items=] of <code>|options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}</code>, if any. For example, if all <code>{{PublicKeyCredentialDescriptor}}</code> [=list/items=] list only <code>{{AuthenticatorTransport/internal}}</code>, but all [=platform authenticator|platform=] |authenticator|s have been tried, then there is no possibility of satisfying the request. Alternatively, all <code>{{PublicKeyCredentialDescriptor}}</code> [=list/items=] may list <code>{{transports}}</code> that the [=client platform=] does not support.

        :   If an |authenticator| becomes available on this [=client device=],
        ::  Note:  This includes the case where an |authenticator| was available upon |lifetimeTimer| initiation.

            1. If <code>|options|.{{PublicKeyCredentialRequestOptions/userVerification}}</code> is set to
                {{UserVerificationRequirement/required}} and the |authenticator| is not capable of performing [=user verification=],
                [=iteration/continue=].

            1. Let |userVerification| be the <dfn>effective user verification requirement for assertion</dfn>, a Boolean value, as
                follows. If <code>|options|.{{PublicKeyCredentialRequestOptions/userVerification}}</code>

                    <dl class="switch">

                        :   is set to {{UserVerificationRequirement/required}}
                        ::  Let |userVerification| be [TRUE].

                        :   is set to {{UserVerificationRequirement/preferred}}
                        ::  If the |authenticator|

                            <dl class="switch">
                                :   is capable of [=user verification=]
                                ::  Let |userVerification| be [TRUE].

                                :   is not capable of [=user verification=]
                                ::  Let |userVerification| be [FALSE].
                            </dl>

                        :   is set to {{UserVerificationRequirement/discouraged}}
                        ::  Let |userVerification| be [FALSE].

                    </dl>

            1. <span id="allowCredentialDescriptorListCreation"></span>
                If <code>|options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}</code>
                <dl class="switch">
                    :   [=list/is not empty=]
                    ::  1. Let |allowCredentialDescriptorList| be a new [=list=].

                        1. Execute a [=client platform=]-specific procedure to determine which, if any, [=public key credentials=] described by
                            <code>|options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}</code> are [=bound credential|bound=] to this
                            |authenticator|, by matching with |rpId|,
                            <code>|options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}.{{PublicKeyCredentialDescriptor/id}}</code>,
                            and
                            <code>|options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}.{{PublicKeyCredentialDescriptor/type}}</code>.
                            Set |allowCredentialDescriptorList| to this filtered list.

                        1. If |allowCredentialDescriptorList| [=list/is empty=], [=continue=].

                        1. Let |distinctTransports| be a new [=ordered set=].

                        1. If |allowCredentialDescriptorList| has exactly one value, set
                            <code>|savedCredentialIds|[|authenticator|]</code> to <code>|allowCredentialDescriptorList|[0].id</code>'s
                            value (see [here](#authenticatorGetAssertion-return-values) in [[#sctn-op-get-assertion]] for more information).

                        1. [=list/For each=] credential descriptor |C| in |allowCredentialDescriptorList|,
                            [=set/append=] each value, if any, of <code>|C|.{{transports}}</code> to |distinctTransports|.

                            Note: This will aggregate only distinct values of {{transports}} (for this [=authenticator=]) in
                                |distinctTransports| due to the properties of [=ordered sets=].

                        1. If |distinctTransports|
                            <dl class="switch">
                                :   [=list/is not empty=]
                                ::  The client selects one |transport| value from |distinctTransports|, possibly incorporating local
                                    configuration knowledge of the appropriate transport to use with |authenticator| in making its
                                    selection.

                                    Then, using |transport|, invoke the [=authenticatorGetAssertion=] operation on
                                    |authenticator|, with |rpId|, |clientDataHash|, |allowCredentialDescriptorList|,
                                    |userVerification|, and |authenticatorExtensions| as parameters.

                                :   [=list/is empty=]
                                ::  Using local configuration knowledge of the appropriate transport to use with |authenticator|,
                                    invoke the [=authenticatorGetAssertion=] operation on |authenticator| with |rpId|,
                                    |clientDataHash|, |allowCredentialDescriptorList|, |userVerification|, and
                                    |authenticatorExtensions| as parameters.
                            </dl>

                    :   [=list/is empty=]
                    ::  Using local configuration knowledge of the appropriate transport to use with |authenticator|, invoke the
                        [=authenticatorGetAssertion=] operation on |authenticator| with |rpId|, |clientDataHash|,
                        |userVerification| and |authenticatorExtensions| as parameters.

                        Note: In this case, the [=[RP]=] did not supply a list of acceptable credential descriptors. Thus, the
                            authenticator is being asked to exercise any credential it may possess that is [=scoped=] to
                            the [=[RP]=], as identified by |rpId|.
                </dl>

            1. [=set/Append=] |authenticator| to |issuedRequests|.

        :   If an |authenticator| ceases to be available on this [=client device=],
        ::  [=set/Remove=] |authenticator| from |issuedRequests|.

        :   If any |authenticator| returns a status indicating that the user cancelled the operation,
        ::  1. [=set/Remove=] |authenticator| from |issuedRequests|.
            1. [=set/For each=] remaining |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation
                on |authenticator| and [=set/remove=] it from |issuedRequests|.

                Note: [=Authenticators=] may return an indication of "the user cancelled the entire operation".
                How a user agent manifests this state to users is unspecified.

        :   If any |authenticator| returns an error status,
        ::  [=set/Remove=] |authenticator| from |issuedRequests|.

        :   If any |authenticator| indicates success,
        ::  1.  [=set/Remove=] |authenticator| from |issuedRequests|.

            1.  <span id="assertionCreationDataCreation"></span>
                Let <var ignore>assertionCreationData</var> be a [=struct=] whose [=items=] are:

                :   <code><dfn for="assertionCreationData">credentialIdResult</code>
                ::  If <code>|savedCredentialIds|[|authenticator|]</code> exists, set the value of [=credentialIdResult=] to be
                    the bytes of <code>|savedCredentialIds|[|authenticator|]</code>. Otherwise, set the value of
                    [=credentialIdResult=] to be the bytes of the [=credential ID=] returned from the successful
                    [=authenticatorGetAssertion=] operation, as defined in [[#sctn-op-get-assertion]].

                :   <code><dfn for="assertionCreationData">clientDataJSONResult</dfn></code>
                ::  whose value is the bytes of |clientDataJSON|.

                :   <code><dfn for="assertionCreationData">authenticatorDataResult</dfn></code>
                ::  whose value is the bytes of the [=authenticator data=] returned by the [=authenticator=].

                :   <code><dfn for="assertionCreationData">signatureResult</dfn></code>
                ::  whose value is the bytes of the signature value returned by the [=authenticator=].

                :   <code><dfn for="assertionCreationData">userHandleResult</dfn></code>
                ::  If the [=authenticator=] returned a [=user handle=], set the value of [=userHandleResult=] to be the bytes of
                    the returned [=user handle=]. Otherwise, set the value of [=userHandleResult=] to null.

                :   <code><dfn for="assertionCreationData">clientExtensionResults</dfn></code>
                ::  whose value is an {{AuthenticationExtensionsClientOutputs}} object containing [=extension identifier=] →
                    [=client extension output=] entries. The entries are created by running each extension's
                    [=client extension processing=] algorithm to create the [=client extension outputs=], for each
                    [=client extension=] in <code>{{AuthenticatorResponse/clientDataJSON}}.clientExtensions</code>.

            1.  Let |constructAssertionAlg| be an algorithm that takes a [=global object=]
                |global|, and whose steps are:

                1.  Let |pubKeyCred| be a new {{PublicKeyCredential}} object associated with |global| whose fields are:

                    :   {{PublicKeyCredential/[[identifier]]}}

                    ::  A new {{ArrayBuffer}}, created using |global|'s [=%ArrayBuffer%=], containing the bytes of
                        <code>|assertionCreationData|.[=credentialIdResult=]</code>.

                    :   {{PublicKeyCredential/response}}
                    ::  A new {{AuthenticatorAssertionResponse}} object associated with |global| whose fields are:

                        :   {{AuthenticatorResponse/clientDataJSON}}
                        ::  A new {{ArrayBuffer}}, created using |global|'s [=%ArrayBuffer%=], containing the bytes of
                            <code>|assertionCreationData|.[=assertionCreationData/clientDataJSONResult=]</code>.

                        :   {{AuthenticatorAssertionResponse/authenticatorData}}
                        ::  A new {{ArrayBuffer}}, created using |global|'s [=%ArrayBuffer%=], containing the bytes of
                            <code>|assertionCreationData|.[=assertionCreationData/authenticatorDataResult=]</code>.

                        :   {{AuthenticatorAssertionResponse/signature}}
                        ::  A new {{ArrayBuffer}}, created using |global|'s [=%ArrayBuffer%=], containing the bytes of
                            <code>|assertionCreationData|.[=assertionCreationData/signatureResult=]</code>.

                        :   {{AuthenticatorAssertionResponse/userHandle}}
                        ::  If <code>|assertionCreationData|.[=assertionCreationData/userHandleResult=]</code> is null, set this
                            field to null. Otherwise, set this field to a new {{ArrayBuffer}}, created using |global|'s
                            [=%ArrayBuffer%=], containing the bytes of
                            <code>|assertionCreationData|.[=assertionCreationData/userHandleResult=]</code>.

                    :   {{PublicKeyCredential/[[clientExtensionsResults]]}}
                    ::  A new {{ArrayBuffer}}, created using |global|'s [=%ArrayBuffer%=], containing the bytes of
                        <code>|assertionCreationData|.[=assertionCreationData/clientExtensionResults=]</code>.

                1.  Return |pubKeyCred|.

            1.  [=set/For each=] remaining |authenticator| in |issuedRequests| invoke the [=authenticatorCancel=] operation
                on |authenticator| and [=set/remove=] it from |issuedRequests|.

            1.  Return |constructAssertionAlg| and terminate this algorithm.
    </dl>

1. Return a {{DOMException}} whose name is "{{NotAllowedError}}". In order to prevent information leak that could identify the
    user without [=user consent|consent=], this step MUST NOT be executed before |lifetimeTimer| has expired. See
    [[#sctn-assertion-privacy]] for details.

During the above process, the user agent SHOULD show some UI to the user to guide them in the process of selecting and
authorizing an authenticator with which to complete the operation.
</div>


### Store an Existing Credential - PublicKeyCredential's `[[Store]](credential, sameOriginWithAncestors)` Method ### {#sctn-storeCredential}

<div link-for-hint="PublicKeyCredential/[[Store]](credential, sameOriginWithAncestors)">

The <dfn for="PublicKeyCredential" method>\[[Store]](credential, sameOriginWithAncestors)</dfn> method is not supported
for Web Authentication's {{PublicKeyCredential}} type, so it always returns an error.

Note: This algorithm is synchronous; the {{Promise}} resolution/rejection is handled by
{{CredentialsContainer/store()|navigator.credentials.store()}}.

This [=internal method=] accepts two arguments:

<dl dfn-type="argument" dfn-for="PublicKeyCredential/[[Store]](credential, sameOriginWithAncestors)">
    :   <dfn>credential</dfn>
    ::  This argument is a {{PublicKeyCredential}} object.

    :   <dfn>sameOriginWithAncestors</dfn>
    ::  This argument is a Boolean value which is [TRUE] if and only if the caller's [=environment settings object=] is
        [=same-origin with its ancestors=].
</dl>

When this method is invoked, the user agent MUST execute the following algorithm:

1. Return a {{DOMException}} whose name is "{{NotSupportedError}}", and terminate this algorithm

</div>

###  Preventing Silent Access to an Existing Credential - PublicKeyCredential's `[[preventSilentAccess]](credential, sameOriginWithAncestors)` Method ### {#sctn-preventSilentAccessCredential}

<div link-for-hint="PublicKeyCredential/[[preventSilentAccess]](credential, sameOriginWithAncestors)">

Calling the <dfn for="PublicKeyCredential" method>\[[preventSilentAccess]](credential, sameOriginWithAncestors)</dfn> method
will have no effect on authenticators that require an [=authorization gesture=],
but setting that flag may potentially exclude authenticators that can operate without user intervention.

This [=internal method=] accepts no arguments.

</div>

### Availability of [=User-Verifying Platform Authenticator=] - PublicKeyCredential's `isUserVerifyingPlatformAuthenticatorAvailable()` Method ### {#sctn-isUserVerifyingPlatformAuthenticatorAvailable}

<div link-for-hint="WebAuthentication/isUserVerifyingPlatformAuthenticatorAvailable">

[=[WRPS]=] use this method to determine whether they can create a new credential using a [=user-verifying platform authenticator=].
Upon invocation, the [=client=] employs a [=client platform=]-specific procedure to discover available [=user-verifying platform authenticators=].
If any are discovered, the promise is resolved with the value of [TRUE].
Otherwise, the promise is resolved with the value of [FALSE].
Based on the result, the [=[RP]=] can take further actions to guide the user to create a credential.

This method has no arguments and returns a Boolean value.

<xmp class="idl">
    partial interface PublicKeyCredential {
        static Promise<boolean> isUserVerifyingPlatformAuthenticatorAvailable();
    };
</xmp>

Note: Invoking this method from a [=browsing context=] where the [=Web Authentication API=] is "disabled" according to the [=allowed to use=] algorithm&mdash;i.e., by a [=feature policy=]&mdash;will result in the promise being rejected with a {{DOMException}} whose name is "{{NotAllowedError}}". See also [[#sctn-feature-policy]].

</div>

## Authenticator Responses (interface <dfn interface>AuthenticatorResponse</dfn>) ## {#iface-authenticatorresponse}

[=Authenticators=] respond to [=[RP]=] requests by returning an object derived from the
{{AuthenticatorResponse}} interface:

<xmp class="idl">
    [SecureContext, Exposed=Window]
    interface AuthenticatorResponse {
        [SameObject] readonly attribute ArrayBuffer      clientDataJSON;
    };
</xmp>
<div dfn-type="attribute" dfn-for="AuthenticatorResponse">
    :   <dfn>clientDataJSON</dfn>
    ::  This attribute contains a [=JSON-serialized client data|JSON serialization=] of the [=client data=] passed to the
        authenticator by the client in its call to either {{CredentialsContainer/create()}} or {{CredentialsContainer/get()}}.
</div>

### Information About Public Key Credential (interface <dfn interface>AuthenticatorAttestationResponse</dfn>) ### {#iface-authenticatorattestationresponse}

The {{AuthenticatorAttestationResponse}} interface represents the [=authenticator=]'s response to a client's request
for the creation of a new [=public key credential=]. It contains information about the new credential that can be used to
identify it for later use, and metadata that can be used by the [=[WRP]=] to assess the characteristics of the credential
during registration.

<xmp class="idl">
    [SecureContext, Exposed=Window]
    interface AuthenticatorAttestationResponse : AuthenticatorResponse {
        [SameObject] readonly attribute ArrayBuffer      attestationObject;
        sequence<DOMString>                              getTransports();
    };
</xmp>
<div dfn-type="attribute" dfn-for="AuthenticatorAttestationResponse">
    :   {{AuthenticatorResponse/clientDataJSON}}
    ::  This attribute, inherited from {{AuthenticatorResponse}}, contains the [=JSON-serialized client data=] (see
        [[#sctn-attestation]]) passed to the authenticator by the client in order to generate this credential. The
        exact JSON serialization MUST be preserved, as the [=hash of the serialized client data=] has been computed
        over it.

    :   <dfn>attestationObject</dfn>
    ::  This attribute contains an [=attestation object=], which is opaque to, and cryptographically protected against
        tampering by, the client. The [=attestation object=] contains both [=authenticator data=] and an [=attestation
        statement=]. The former contains the AAGUID, a unique [=credential ID=], and the [=credential public key=]. The
        contents of the [=attestation statement=] are determined by the [=attestation statement format=] used by the
        [=authenticator=]. It also contains any additional information that the [=[RP]=]'s server requires to validate the
        [=attestation statement=], as well as to decode and validate the [=authenticator data=] along with the
        [=JSON-serialized client data=]. For more details, see [[#sctn-attestation]], [[#sctn-generating-an-attestation-object]],
        and [Figure 6](#fig-attStructs).

    :   {{AuthenticatorAttestationResponse/getTransports()}}
    ::  This operation returns the value of {{AuthenticatorAttestationResponse/[[transports]]}}.

    :   <dfn>\[[transports]]</dfn>
    ::  This [=internal slot=] contains a sequence of zero or more unique {{DOMString}}s in lexicographical order. These values are the transports that the [=authenticator=] is believed to support, or an empty sequence if the information is unavailable. The values SHOULD be members of {{AuthenticatorTransport}} but [=[RPS]=] MUST accept unknown values.
</div>

### Web Authentication Assertion (interface <dfn interface>AuthenticatorAssertionResponse</dfn>) ### {#iface-authenticatorassertionresponse}

The {{AuthenticatorAssertionResponse}} interface represents an [=authenticator=]'s response to a client's request for
generation of a new [=authentication assertion=] given the [=[WRP]=]'s challenge and OPTIONAL list of credentials it is
aware of. This response contains a cryptographic signature proving possession of the [=credential private key=], and
optionally evidence of [=user consent=] to a specific transaction.

<xmp class="idl">
    [SecureContext, Exposed=Window]
    interface AuthenticatorAssertionResponse : AuthenticatorResponse {
        [SameObject] readonly attribute ArrayBuffer      authenticatorData;
        [SameObject] readonly attribute ArrayBuffer      signature;
        [SameObject] readonly attribute ArrayBuffer?     userHandle;
    };
</xmp>
<div dfn-type="attribute" dfn-for="AuthenticatorAssertionResponse">
    :   {{AuthenticatorResponse/clientDataJSON}}
    ::  This attribute, inherited from {{AuthenticatorResponse}}, contains the [=JSON-serialized client data=] (see
        [[#dictionary-client-data]]) passed to the authenticator by the client in order to generate this assertion. The
        exact JSON serialization MUST be preserved, as the [=hash of the serialized client data=] has been computed
        over it.

    :   <dfn>authenticatorData</dfn>
    ::  This attribute contains the [=authenticator data=] returned by the authenticator. See [[#sctn-authenticator-data]].

    :   <dfn>signature</dfn>
    ::  This attribute contains the raw signature returned from the authenticator. See [[#sctn-op-get-assertion]].

    :   <dfn>userHandle</dfn>
    ::  This attribute contains the [=user handle=] returned from the authenticator, or null if the authenticator did not return a
        [=user handle=]. See [[#sctn-op-get-assertion]].
</div>

## Parameters for Credential Generation (dictionary <dfn dictionary>PublicKeyCredentialParameters</dfn>) ## {#dictionary-credential-params}

<xmp class="idl">
    dictionary PublicKeyCredentialParameters {
        required PublicKeyCredentialType      type;
        required COSEAlgorithmIdentifier      alg;
    };
</xmp>

<div dfn-type="dict-member" dfn-for="PublicKeyCredentialParameters">
    This dictionary is used to supply additional parameters when creating a new credential.

    :   <dfn>type</dfn>
    ::  This member specifies the type of credential to be created.

    :   <dfn>alg</dfn>
    ::  This member specifies the cryptographic signature algorithm with which the newly generated credential will be used, and
        thus also the type of asymmetric key pair to be generated, e.g., RSA or Elliptic Curve.

    Note: we use "alg" as the latter member name, rather than spelling-out "algorithm", because it will be serialized into
        a message to the authenticator, which may be sent over a low-bandwidth link.
</div>

## Options for Credential Creation (dictionary <dfn dictionary>PublicKeyCredentialCreationOptions</dfn>) ## {#dictionary-makecredentialoptions}

<xmp class="idl">
    dictionary PublicKeyCredentialCreationOptions {
        required PublicKeyCredentialRpEntity         rp;
        required PublicKeyCredentialUserEntity       user;

        required BufferSource                             challenge;
        required sequence<PublicKeyCredentialParameters>  pubKeyCredParams;

        unsigned long                                timeout;
        sequence<PublicKeyCredentialDescriptor>      excludeCredentials = [];
        AuthenticatorSelectionCriteria               authenticatorSelection;
        AttestationConveyancePreference              attestation = "none";
        AuthenticationExtensionsClientInputs         extensions;
    };
</xmp>
<div dfn-type="dict-member" dfn-for="PublicKeyCredentialCreationOptions">
    :   <dfn>rp</dfn>
    ::  This member contains data about the [=[RP]=] responsible for the request.

        Its value's {{PublicKeyCredentialEntity/name}} member is REQUIRED. See [[#dictionary-pkcredentialentity]] for further
        details.

        Its value's {{PublicKeyCredentialRpEntity/id}} member specifies the [=RP ID=] the credential
        should be [=scoped=] to. If omitted, its value will be the {{CredentialsContainer}} object's [=relevant
        settings object=]'s [=environment settings object/origin=]'s [=effective domain=]. See [[#dictionary-rp-credential-params]]
        for further details.

    :   <dfn>user</dfn>
    ::  This member contains data about the user account for which the [=[RP]=] is requesting attestation.

        Its value's {{PublicKeyCredentialEntity/name}}, {{PublicKeyCredentialUserEntity/displayName}} and
        {{PublicKeyCredentialUserEntity/id}} members are REQUIRED. See [[#dictionary-pkcredentialentity]] and
        [[#dictionary-user-credential-params]] for further details.

    :   <dfn>challenge</dfn>
    ::  This member contains a challenge intended to be used for generating the newly created credential's [=attestation
        object=]. See the [[#sctn-cryptographic-challenges]] security consideration.

    :   <dfn>pubKeyCredParams</dfn>
    ::  This member contains information about the desired properties of the credential to be created. The sequence is ordered
        from most preferred to least preferred. The [=client=] makes a best-effort to create the most preferred credential that it
        can.

    :   <dfn>timeout</dfn>
    ::  This member specifies a time, in milliseconds, that the caller is willing to wait for the call to complete. This is
        treated as a hint, and MAY be overridden by the [=client=].

    :   <dfn>excludeCredentials</dfn>
    ::  This member is intended for use by [=[RPS]=] that wish to limit the creation of multiple credentials for the same
        account on a single authenticator. The [=client=] is requested to return an error if the new credential would be created
        on an authenticator that also contains one of the credentials enumerated in this parameter.

    :   <dfn>authenticatorSelection</dfn>
    ::  This member is intended for use by [=[RPS]=] that wish to select the appropriate authenticators to participate in
        the {{CredentialsContainer/create()}} operation.

    :   <dfn>attestation</dfn>
    ::  This member is intended for use by [=[RPS]=] that wish to express their preference for [=attestation conveyance=].
        The default is {{AttestationConveyancePreference/none}}.

    :   <dfn>extensions</dfn>
    ::  This member contains additional parameters requesting additional processing by the client and authenticator. For
        example, the caller may request that only authenticators with certain capabilities be used to create the credential, or
        that particular information be returned in the [=attestation object=]. Some extensions are defined in [[#sctn-extensions]];
        consult the IANA "WebAuthn Extension Identifier" registry established by [[!WebAuthn-Registries]] for an up-to-date list
        of registered [=WebAuthn Extensions=].
</div>

### Public Key Entity Description (dictionary <dfn dictionary>PublicKeyCredentialEntity</dfn>) ### {#dictionary-pkcredentialentity}

The {{PublicKeyCredentialEntity}} dictionary describes a user account, or a [=[WRP]=], which a [=public key credential=] is
associated with or [=scoped=] to, respectively.

<xmp class="idl">
    dictionary PublicKeyCredentialEntity {
        required DOMString    name;
    };
</xmp>
<div dfn-type="dict-member" dfn-for="PublicKeyCredentialEntity">
    :   <dfn>name</dfn>
    ::  A [=human palatability|human-palatable=] name for the entity. Its function depends on what the {{PublicKeyCredentialEntity}} represents:

          - When inherited by {{PublicKeyCredentialRpEntity}} it is a [=human palatability|human-palatable=] identifier for the [=[RP]=], intended only
            for display. For example, "ACME Corporation", "Wonderful Widgets, Inc." or "ОАО Примертех".

              - [=[RPS]=] SHOULD perform enforcement, as prescribed in Section 2.3 of
                [[!RFC8266]] for the Nickname Profile of the PRECIS FreeformClass [[!RFC8264]],
                when setting {{PublicKeyCredentialEntity/name}}'s value, or displaying the value to the user.

              - [=Clients=] SHOULD perform enforcement, as prescribed in Section 2.3 of
                [[!RFC8266]] for the Nickname Profile of the PRECIS FreeformClass [[!RFC8264]],
                on {{PublicKeyCredentialEntity/name}}'s value prior to displaying the value to the user or
                including the value as a parameter of the [=authenticatorMakeCredential=] operation.

          - When inherited by {{PublicKeyCredentialUserEntity}}, it is a [=human palatability|human-palatable=] identifier for a
            user account. It is intended only for display, i.e., aiding the user in determining the difference between user
            accounts with similar {{PublicKeyCredentialUserEntity/displayName}}s. For example, "alexm", "alex.p.mueller@example.com"
            or "+14255551234".

              - The [=[RP]=] MAY let the user choose this value. The [=[RP]=] SHOULD perform enforcement,
                as prescribed in Section 3.4.3 of [[!RFC8265]] for the UsernameCasePreserved Profile of the PRECIS
                IdentifierClass [[!RFC8264]], when setting {{PublicKeyCredentialEntity/name}}'s value, or displaying the value
                to the user.

              - [=Clients=] SHOULD perform enforcement, as prescribed in Section 3.4.3 of [[!RFC8265]]
                for the UsernameCasePreserved Profile of the PRECIS IdentifierClass [[!RFC8264]],
                on {{PublicKeyCredentialEntity/name}}'s value prior to displaying the value to the user or
                including the value as a parameter of the [=authenticatorMakeCredential=] operation.


        When [=clients=], [=client platforms=], or [=authenticators=] display a {{PublicKeyCredentialEntity/name}}'s value, they should always use UI elements to provide a clear boundary around the displayed value, and not allow overflow into other elements [[css-overflow-3]].

        [=Authenticators=] MUST accept and store a 64-byte minimum length for a {{PublicKeyCredentialEntity/name}} member's
        value. Authenticators MAY truncate a {{PublicKeyCredentialEntity/name}} member's value so that it fits within 64 bytes. See [[#sctn-strings]] about truncation and other considerations.
</div>


### Relying Party Parameters for Credential Generation (dictionary <dfn dictionary>PublicKeyCredentialRpEntity</dfn>) ### {#dictionary-rp-credential-params}

The {{PublicKeyCredentialRpEntity}} dictionary is used to supply additional [=[RP]=] attributes when creating a new credential.

<xmp class="idl">
    dictionary PublicKeyCredentialRpEntity : PublicKeyCredentialEntity {
        DOMString      id;
    };
</xmp>

<div dfn-type="dict-member" dfn-for="PublicKeyCredentialRpEntity">
    :   <dfn>id</dfn>
    ::  A unique identifier for the [=[RP]=] entity, which sets the [=RP ID=].
</div>


### User Account Parameters for Credential Generation (dictionary <dfn dictionary>PublicKeyCredentialUserEntity</dfn>) ### {#dictionary-user-credential-params}

The {{PublicKeyCredentialUserEntity}} dictionary is used to supply additional user account attributes when creating a new
credential.

<xmp class="idl">
    dictionary PublicKeyCredentialUserEntity : PublicKeyCredentialEntity {
        required BufferSource   id;
        required DOMString      displayName;
    };
</xmp>

<div dfn-type="dict-member" dfn-for="PublicKeyCredentialUserEntity">
    :   <dfn>id</dfn>
    ::  The [=user handle=] of the user account entity.
        A [=user handle=] is an opaque [=byte sequence=] with a maximum size of 64 bytes,
        and is not meant to be displayed to the user.

        To ensure secure operation, authentication and authorization
        decisions MUST be made on the basis of this {{PublicKeyCredentialUserEntity/id}} member,  not the
        {{PublicKeyCredentialUserEntity/displayName}} nor {{PublicKeyCredentialEntity/name}} members. See Section 6.1 of [[!RFC8266]].

        The [=user handle=] MUST NOT contain [PII] about the user, such as a username or e-mail address;
        see [[#sctn-user-handle-privacy]] for details.

    :   <dfn>displayName</dfn>
    ::  A [=human palatability|human-palatable=] name for the user account, intended only for display. For example, "Alex P. Müller" or "田中 倫". The
        [=[RP]=] SHOULD let the user choose this, and SHOULD NOT restrict the choice more than necessary.

        - [=[RPS]=] SHOULD perform enforcement, as prescribed in Section 2.3 of
            [[!RFC8266]] for the Nickname Profile of the PRECIS FreeformClass [[!RFC8264]],
            when setting {{PublicKeyCredentialUserEntity/displayName}}'s value, or displaying the value to the user.

        - [=Clients=] SHOULD perform enforcement, as prescribed in Section 2.3 of
            [[!RFC8266]] for the Nickname Profile of the PRECIS FreeformClass [[!RFC8264]],
            on {{PublicKeyCredentialUserEntity/displayName}}'s value prior to displaying the value to the user or
            including the value as a parameter of the [=authenticatorMakeCredential=] operation.

        When [=clients=], [=client platforms=], or [=authenticators=] display a {{PublicKeyCredentialUserEntity/displayName}}'s value, they should always use UI elements to provide a clear boundary around the displayed value, and not allow overflow into other elements [[css-overflow-3]].

        [=Authenticators=] MUST accept and store a 64-byte minimum length for a {{PublicKeyCredentialUserEntity/displayName}}
        member's value. Authenticators MAY truncate a {{PublicKeyCredentialUserEntity/displayName}} member's value so that it fits within 64 bytes. See [[#sctn-strings]] about truncation and other considerations.
</div>


### Authenticator Selection Criteria (dictionary <dfn dictionary>AuthenticatorSelectionCriteria</dfn>) ### {#dictionary-authenticatorSelection}

[=[WRPS]=] may use the {{AuthenticatorSelectionCriteria}} dictionary to specify their requirements regarding authenticator
attributes.

<xmp class="idl">
    dictionary AuthenticatorSelectionCriteria {
        AuthenticatorAttachment      authenticatorAttachment;
        boolean                      requireResidentKey = false;
        ResidentKeyRequirement       residentKey;
        UserVerificationRequirement  userVerification = "preferred";
    };
</xmp>

<div dfn-type="dict-member" dfn-for="AuthenticatorSelectionCriteria">
    :   <dfn>authenticatorAttachment</dfn>
    ::  If this member is [=present|present=], eligible authenticators are filtered to only authenticators attached with the
        specified [[#enum-attachment]].

    :   <dfn>requireResidentKey</dfn>
    ::  Note: This member is retained for backwards compatibility with WebAuthn Level 1 but is deprecated in favour of {{residentKey}}.
        {{requireResidentKey}} is ignored if the caller supplies {{residentKey}} and the latter is understood by the [=client=].
        Otherwise, {{requireResidentKey}}'s value is used. Note that {{requireResidentKey}}'s value defaults to [FALSE].

        If used in absence of {{residentKey}}, it describes the [=[RP]=]'s requirements regarding [=resident credentials=].
        If {{requireResidentKey}} is set to [TRUE], the authenticator MUST create a [=client-side-resident public key credential source=]
        when creating a [=public key credential=].

    :   <dfn>residentKey</dfn>
    ::  Note: This member supersedes {{requireResidentKey}}. If both are present and the [=client=] understands {{residentKey}}, then
        {{residentKey}} is used and {{requireResidentKey}} is ignored.

        See {{ResidentKeyRequirement}} for the description of {{residentKey}}'s values and semantics.

    :   <dfn>userVerification</dfn>
    ::  This member describes the [=[RP]=]'s requirements regarding [=user verification=] for the
        {{CredentialsContainer/create()}} operation. Eligible authenticators are filtered to only those capable of satisfying this
        requirement.
</div>


### Authenticator Attachment Enumeration (enum <dfn enum>AuthenticatorAttachment</dfn>) ### {#enum-attachment}

This enumeration's values describe [=authenticators=]' [=authenticator attachment modality|attachment modalities=].
[=[RPS]=] use this to express a preferred [=authenticator attachment modality=]
when calling {{CredentialsContainer/create()|navigator.credentials.create()}}
to [[#sctn-createCredential|create a credential]].

<xmp class="idl">
    enum AuthenticatorAttachment {
        "platform",
        "cross-platform"
    };
</xmp>

<div dfn-type="enum-value" dfn-for="AuthenticatorAttachment">
    :   <dfn>platform</dfn>
    ::  This value indicates [=platform attachment=].

    :   <dfn>cross-platform</dfn>
    ::  This value indicates [=cross-platform attachment=].
</div>

Note: An [=authenticator attachment modality=] selection option is available only in the {{PublicKeyCredential/[[Create]](origin, options,
sameOriginWithAncestors)}} operation. The [=[RP]=] may use it to, for example, ensure the user has a [=roaming credential=] for
authenticating on another [=client device=]; or to specifically register a [=platform credential=] for easier reauthentication using a
particular [=client device=]. The {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)}}
operation has no [=authenticator attachment modality=] selection option, so the [=[RP]=] SHOULD accept any of the user's registered [=public key
credential|credentials=]. The [=client=] and user will then use whichever is available and convenient at the time.


### Resident Key Requirement Enumeration (enum <dfn enum>ResidentKeyRequirement</dfn>) ### {#enum-residentKeyRequirement}

<xmp class="idl">
    enum ResidentKeyRequirement {
        "discouraged",
        "preferred",
        "required"
    };
</xmp>

This enumeration's values describe the [=[RP]=]'s requirements for [=resident credentials=]:

<div dfn-type="enum-value" dfn-for="ResidentKeyRequirement">
    :   <dfn>discouraged</dfn>
    ::  This value indicates the [=[RP]=] prefers creating a [=non-resident credential=], but will accept a
        [=resident credential=].

    :   <dfn>preferred</dfn>
    ::  This value indicates the [=[RP]=] prefers creating a [=resident credential=], but will accept a
        [=non-resident credential=].

    :   <dfn>required</dfn>
    ::  This value indicates the [=[RP]=] requires a [=resident credential=], and is prepared to receive an error
        if a [=resident credential=] cannot be created.
</div>

Note: The [=[RP]=] can use a combination of the value provided for |options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{residentKey}}
and the [=credProps|Credential Properties Extension=]'s return value to determine  whether or not the authenticator created a [=resident credential=].
This is useful when values of  {{ResidentKeyRequirement/discouraged}} or {{ResidentKeyRequirement/preferred}} are used for
|options|.{{PublicKeyCredentialCreationOptions/authenticatorSelection}}.{{residentKey}}, because in those cases it is possible for an
[=authenticator=] to create either a [=resident credential=] or a [=non-resident credential=].


### <dfn>Attestation Conveyance</dfn> Preference Enumeration (enum <dfn enum>AttestationConveyancePreference</dfn>) ### {#enum-attestation-convey}

[=[WRPS]=] may use {{AttestationConveyancePreference}} to specify their preference regarding [=attestation conveyance=]
during credential generation.

<xmp class="idl">
    enum AttestationConveyancePreference {
        "none",
        "indirect",
        "direct"
    };
</xmp>

<div dfn-type="enum-value" dfn-for="AttestationConveyancePreference">
    :   <dfn>none</dfn>
    ::  This value indicates that the [=[RP]=] is not interested in [=authenticator=] [=attestation=]. For example, in order to
        potentially avoid having to obtain [=user consent=] to relay identifying information to the [=[RP]=], or to save a
        roundtrip to an [=Attestation CA=].

        This is the default value.

    :   <dfn>indirect</dfn>
    ::  This value indicates that the [=[RP]=] prefers an [=attestation=] conveyance yielding verifiable [=attestation
        statements=], but allows the client to decide how to obtain such [=attestation statements=].  The client MAY replace the
        authenticator-generated [=attestation statements=] with [=attestation statements=] generated by an [=Anonymization CA=],
        in order to protect the user's privacy, or to assist [=[RPS]=] with attestation verification in a heterogeneous ecosystem.

        Note: There is no guarantee that the [=[RP]=] will obtain a verifiable [=attestation statement=] in this case.
        For example, in the case that the authenticator employs [=self attestation=].

    :   <dfn>direct</dfn>
    ::  This value indicates that the [=[RP]=] wants to receive the [=attestation statement=] as generated by the
        [=authenticator=].

</div>


## Options for Assertion Generation (dictionary <dfn dictionary>PublicKeyCredentialRequestOptions</dfn>) ## {#dictionary-assertion-options}

The {{PublicKeyCredentialRequestOptions}} dictionary supplies {{CredentialsContainer/get()}} with the data it needs to generate
an assertion. Its {{PublicKeyCredentialRequestOptions/challenge}} member MUST be present, while its other members are OPTIONAL.

<xmp class="idl">
    dictionary PublicKeyCredentialRequestOptions {
        required BufferSource                challenge;
        unsigned long                        timeout;
        USVString                            rpId;
        sequence<PublicKeyCredentialDescriptor> allowCredentials = [];
        UserVerificationRequirement          userVerification = "preferred";
        AuthenticationExtensionsClientInputs extensions;
    };
</xmp>

<dl dfn-type="dict-member" dfn-for="PublicKeyCredentialRequestOptions">
    :   <dfn>challenge</dfn>
    ::  This member represents a challenge that the selected [=authenticator=] signs, along with other data, when producing an
        [=authentication assertion=]. See the [[#sctn-cryptographic-challenges]] security consideration.

    :   <dfn>timeout</dfn>
    ::  This OPTIONAL member specifies a time, in milliseconds, that the caller is willing to wait for the call to complete.
        The value is treated as a hint, and MAY be overridden by the [=client=].

    :   <dfn>rpId</dfn>
    ::  This OPTIONAL member specifies the [=relying party identifier=] claimed by the caller. If omitted, its value will
        be the {{CredentialsContainer}} object's [=relevant settings object=]'s [=environment settings object/origin=]'s
        [=effective domain=].

    :   <dfn>allowCredentials</dfn>
    ::  This OPTIONAL member contains a list of {{PublicKeyCredentialDescriptor}} objects representing [=public key credentials=]
        acceptable to the caller, in descending order of the caller's preference (the first item in the list is the most
        preferred credential, and so on down the list).

    :   <dfn>userVerification</dfn>
    ::  This OPTIONAL member describes the [=[RP]=]'s requirements regarding [=user verification=] for the
        {{CredentialsContainer/get()}} operation. Eligible authenticators are filtered to only those capable of satisfying this
        requirement.

    :   <dfn>extensions</dfn>
    ::  This OPTIONAL member contains additional parameters requesting additional processing by the client and authenticator.
        For example, if transaction confirmation is sought from the user, then the prompt string might be included as an
        extension.
</dl>


## Abort Operations with `AbortSignal` ## {#sctn-abortoperation}

Developers are encouraged to leverage the {{AbortController}} to manage the
{{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)}} and {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)}} operations.
See [[dom#abortcontroller-api-integration]] section for detailed instructions.

    Note: [[dom#abortcontroller-api-integration]] section specifies that web platform APIs integrating with the
    {{AbortController}} must reject the promise immediately once the [=AbortSignal/aborted flag=] is set.
    Given the complex inheritance and parallelization structure of the {{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)}}
    and {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)}} methods, the algorithms for the two APIs fulfills this
    requirement by checking the [=AbortSignal/aborted flag=] in three places. In the case of
    {{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)}}, the aborted flag is checked first in
    [[credential-management-1#algorithm-create]] immediately before calling {{Credential/[[Create]](origin, options, sameOriginWithAncestors)}},
    then in [[#sctn-createCredential]] right before [=authenticator sessions=] start, and finally
    during [=authenticator sessions=]. The same goes for
    {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)}}.

The [=visibility states|visibility=] and [=focus=] state of the [=Window=] object determines whether the
{{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)}} and {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)}} operations
should continue. When the [=Window=] object associated with the [[=Document=] loses focus,
{{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)}} and {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)}} operations
SHOULD be aborted.

    Issue: The WHATWG HTML WG is discussing whether to provide a hook when a browsing context gains or
    loses focuses. If a hook is provided, the above paragraph will be updated to include the hook.
    See [WHATWG HTML WG Issue #2711](https://github.com/whatwg/html/issues/2711) for more details.


## WebAuthn Extensions Inputs and Outputs ## {#sctn-extensions-inputs-outputs}

The subsections below define the data types used for conveying [=WebAuthn extension=] inputs and outputs.

Note: [=Authenticator extension outputs=] are conveyed as a part of [=Authenticator data=] (see [Table 1](#table-authData)).

Note: The types defined below&mdash;{{AuthenticationExtensionsClientInputs}}, {{AuthenticationExtensionsClientOutputs}}, and {{AuthenticationExtensionsAuthenticatorInputs}}&mdash;are applicable to both [=registration extensions=] and [=authentication extensions=]. The "Authentication..." portion of their names should be regarded as meaning "WebAuthentication..."


### Authentication Extensions Client Inputs (dictionary {{AuthenticationExtensionsClientInputs}}) ## {#iface-authentication-extensions-client-inputs}

<xmp class="idl">
    dictionary AuthenticationExtensionsClientInputs {
    };
</xmp>

This is a dictionary containing the [=client extension input=] values for zero or more [=WebAuthn Extensions=].


### Authentication Extensions Client Outputs (dictionary {{AuthenticationExtensionsClientOutputs}}) ## {#iface-authentication-extensions-client-outputs}

<xmp class="idl">
    dictionary AuthenticationExtensionsClientOutputs {
    };
</xmp>

This is a dictionary containing the [=client extension output=] values for zero or more [=WebAuthn Extensions=].


### Authentication Extensions Authenticator Inputs (typedef {{AuthenticationExtensionsAuthenticatorInputs}}) ## {#iface-authentication-extensions-authenticator-inputs}

<xmp class="idl">
    typedef record<DOMString, DOMString> AuthenticationExtensionsAuthenticatorInputs;
</xmp>

This is a dictionary containing the [=authenticator extension input=] values for zero or more [=WebAuthn Extensions=].


## Supporting Data Structures ## {#sctn-supporting-data-structures}

The [=public key credential=] type uses certain data structures that are specified in supporting specifications. These are as
follows.


### Client Data Used in [=WebAuthn Signatures=] (dictionary <dfn dictionary>CollectedClientData</dfn>) ### {#dictionary-client-data}

The <dfn>client data</dfn> represents the contextual bindings of both the [=[WRP]=] and the [=client=]. It is a key-value
mapping whose keys are strings. Values can be any type that has a valid encoding in JSON. Its structure is defined by the
following Web IDL.

Note: The {{CollectedClientData}} may be extended in the future. Therefore it's critical when parsing to be tolerant of unknown keys and of any reordering of the keys.

<xmp class="idl">
    dictionary CollectedClientData {
        required DOMString           type;
        required DOMString           challenge;
        required DOMString           origin;
        boolean                      crossOrigin;
        TokenBinding                 tokenBinding;
    };

    dictionary TokenBinding {
        required TokenBindingStatus status;
        DOMString id;
    };

    enum TokenBindingStatus { "present", "supported" };
</xmp>

<div dfn-type="dict-member" dfn-for="CollectedClientData">
    :   <dfn>type</dfn>
    ::  This member contains the string "webauthn.create" when creating new credentials, and "webauthn.get" when getting an
        assertion from an existing credential. The purpose of this member is to prevent certain types of signature confusion
        attacks (where an attacker substitutes one legitimate signature for another).

    :   <dfn>challenge</dfn>
    ::  This member contains the base64url encoding of the challenge provided by the [=[RP]=]. See the [[#sctn-cryptographic-challenges]]
        security consideration.

    :   <dfn>origin</dfn>
    ::  This member contains the fully qualified [=origin=] of the requester, as provided to the authenticator by the client, in
        the syntax defined by [[!RFC6454]].

    :   <dfn>crossOrigin</dfn>
    ::  This member contains the inverse of the `sameOriginWithAncestors` argument value
        that was passed into the [=internal method=].

    :   <dfn>tokenBinding</dfn>
    ::  This OPTIONAL member contains information about the state of the [=Token Binding=] protocol [[!TokenBinding]] used when communicating
        with the [=[RP]=]. Its absence indicates that the client doesn't support token binding.

        <div dfn-type="dict-member" dfn-for="TokenBinding">
            :   <dfn>status</dfn>
            ::  This member is one of the following:

                <div dfn-type="enum-value" dfn-for="TokenBindingStatus">
                    :   <dfn>supported</dfn>
                    ::  Indicates the client supports token binding, but it was not negotiated when communicating with the [=[RP]=].

                    :   <dfn>present</dfn>
                    ::  Indicates token binding was used when communicating with the [=[RP]=]. In this case, the
                        {{TokenBinding/id}} member MUST be present.
                </div>

            :   <dfn>id</dfn>
            ::  This member MUST be present if {{TokenBinding/status}} is {{TokenBindingStatus/present}}, and MUST be a [=base64url
                encoding=] of the [=Token Binding ID=] that was used when communicating with the [=[RP]=].
        </div>

        Note: Obtaining a [=Token Binding ID=] is a [=client platform=]-specific operation.

    The {{CollectedClientData}} structure is used by the client to compute the following quantities:

    : <dfn dfn>JSON-serialized client data</dfn>
    :: This is the result of [=serialize JSON to bytes|JSON-serializing to bytes=] a
        {{CollectedClientData}} dictionary.

    : <dfn dfn>Hash of the serialized client data</dfn>
    :: This is the hash (computed using SHA-256) of the [=JSON-serialized client data=], as constructed by the client.
</div>


### Credential Type Enumeration (enum <dfn enum>PublicKeyCredentialType</dfn>) ### {#enum-credentialType}

<xmp class="idl">
    enum PublicKeyCredentialType {
        "public-key"
    };
</xmp>

<div dfn-type="enum-value" dfn-for="PublicKeyCredentialType">
    This enumeration defines the valid credential types. It is an extension point; values can be added to it in the future, as
    more credential types are defined. The values of this enumeration are used for versioning the Authentication Assertion and
    attestation structures according to the type of the authenticator.

    Currently one credential type is defined, namely "<dfn>public-key</dfn>".
</div>


### Credential Descriptor (dictionary <dfn dictionary>PublicKeyCredentialDescriptor</dfn>) ### {#dictionary-credential-descriptor}

<xmp class="idl">
    dictionary PublicKeyCredentialDescriptor {
        required PublicKeyCredentialType      type;
        required BufferSource                 id;
        sequence<DOMString>                   transports;
    };
</xmp>

This dictionary contains the attributes that are specified by a caller when referring to a [=public key credential=] as an input
parameter to the {{CredentialsContainer/create()}} or {{CredentialsContainer/get()}} methods. It mirrors the fields of the
{{PublicKeyCredential}} object returned by the latter methods.

<div dfn-type="dict-member" dfn-for="PublicKeyCredentialDescriptor">
    :   <dfn>type</dfn>
    ::  This member contains the type of the [=public key credential=] the caller is referring to.

    :   <dfn>id</dfn>
    ::  This member contains the [=credential ID=] of the [=public key credential=] the caller is referring to.

    :   <dfn>transports</dfn>
    ::  This OPTIONAL member contains a hint as to how the [=client=] might communicate with the [=managing authenticator=] of the
        [=public key credential=] the caller is referring to. The values SHOULD be members of {{AuthenticatorTransport}} but [=client platforms=] MUST ignore unknown values.
        The {{AuthenticatorAttestationResponse/getTransports()}} operation can provide suitable values for this member.
</div>


### Authenticator Transport Enumeration (enum <dfn enum>AuthenticatorTransport</dfn>) ### {#enum-transport}

<xmp class="idl">
    enum AuthenticatorTransport {
        "usb",
        "nfc",
        "ble",
        "internal",
        "lightning"
    };
</xmp>

<div dfn-type="enum-value" dfn-for="AuthenticatorTransport">
    [=Authenticators=] may implement various [[#enum-transport|transports]] for communicating with [=clients=]. This enumeration
    defines hints as to how clients might communicate with a particular authenticator in order to obtain an assertion for a
    specific credential. Note that these hints represent the [=[WRP]=]'s best belief as to how an authenticator may be reached. A
    [=[RP]=] will typically learn of the supported transports for a [=public key credential=] via
    {{AuthenticatorAttestationResponse/getTransports()}}.

    Note: The {{AuthenticatorTransport}} enumeration is not referenced by other parts of the Web IDL because that would preclude other values from being used without updating this specification and its implementations. It is important for backwards compatibility that [=client platforms=] and [=[RPS]=] handle unknown values. Therefore it exists here for documentation and as a registry. Where transports are represented elsewhere, they are typed as {{DOMString}}s, for example in {{PublicKeyCredentialDescriptor/transports}}.

    :   <dfn>usb</dfn>
    ::  Indicates the respective [=authenticator=] can be contacted over removable USB.

    :   <dfn>lightning</dfn>
    ::  Indicates the respective [=authenticator=] can be contacted over removable Lightning.

    :   <dfn>nfc</dfn>
    ::  Indicates the respective [=authenticator=] can be contacted over Near Field Communication (NFC).

    :   <dfn>ble</dfn>
    ::  Indicates the respective [=authenticator=] can be contacted over Bluetooth Smart (Bluetooth Low Energy / BLE).

    :   <dfn>internal</dfn>
    ::  Indicates the respective [=authenticator=] is contacted using a [=client device=]-specific transport,
        i.e., it is a [=platform authenticator=].
        These authenticators are not removable from the [=client device=].
</div>


### Cryptographic Algorithm Identifier (typedef {{COSEAlgorithmIdentifier}}) ### {#sctn-alg-identifier}

<xmp class="idl">
    typedef long COSEAlgorithmIdentifier;
</xmp>

<div dfn-type="typedef" dfn-for="COSEAlgorithmIdentifier">
    A {{COSEAlgorithmIdentifier}}'s value is a number identifying a cryptographic algorithm.
    The algorithm identifiers SHOULD be values registered in the IANA COSE Algorithms registry [[!IANA-COSE-ALGS-REG]],
    for instance, <code>-7</code> for "ES256" and <code>-257</code> for "RS256".
</div>


### User Verification Requirement Enumeration (enum <dfn enum>UserVerificationRequirement</dfn>) ### {#enum-userVerificationRequirement}

<xmp class="idl">
    enum UserVerificationRequirement {
        "required",
        "preferred",
        "discouraged"
    };
</xmp>

A [=[WRP]=] may require [=user verification=] for some of its operations but not for others, and may use this type to express its
needs.

<div dfn-type="enum-value" dfn-for="UserVerificationRequirement">
    :   <dfn>required</dfn>
    ::  This value indicates that the [=[RP]=] requires [=user verification=] for the operation and will fail the operation if the
        response does not have the [=UV=] [=flag=] set.

    :   <dfn>preferred</dfn>
    ::  This value indicates that the [=[RP]=] prefers [=user verification=] for the operation if possible, but will not fail the
        operation if the response does not have the [=UV=] [=flag=] set.

    :   <dfn>discouraged</dfn>
    ::  This value indicates that the [=[RP]=] does not want [=user verification=] employed during the operation (e.g., in the
        interest of minimizing disruption to the user interaction flow).
</div>


## Feature Policy integration ## {#sctn-feature-policy}

This specification defines a [=policy-controlled feature=] identified by
the feature-identifier token "<code><dfn data-lt="publickey-credentials-feature" export>publickey-credentials</dfn></code>".
Its [=default allowlist=] is '<code>self</code>'. [[!Feature-Policy]]

A {{Document}}'s [=Document/feature policy=] determines whether any content in that <a href="https://html.spec.whatwg.org/multipage/dom.html#documents">document</a> is
[=allowed to use|allowed to successfully invoke=] the [=Web Authentication API=], i.e., via
<code><a idl for="CredentialsContainer" lt="create()">navigator.credentials.create({publicKey:..., ...})</a></code> and
<code><a idl for="CredentialsContainer" lt="get()">navigator.credentials.get({publicKey:..., ...})</a></code>.
If disabled in any document, no content in the document will be [=allowed to use=]
the foregoing methods: attempting to do so will [return an error](https://www.w3.org/2001/tag/doc/promises-guide#errors).

Note: Algorithms specified in [[!CREDENTIAL-MANAGEMENT-1]] perform the actual feature policy evaluation. This is because such policy evaluation needs to occur when there is access to the [=current settings object=]. The {{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)}} and {{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)}} [=internal methods=] do not have such access since they are invoked [=in parallel=] (by algorithms specified in [[!CREDENTIAL-MANAGEMENT-1]]).



## Using Web Authentication within <code>iframe</code> elements ## {#sctn-iframe-guidance}

The [=Web Authentication API=] is disabled by default in cross-origin <{iframe}>s.
To override this default policy and indicate that a cross-origin <{iframe}> is allowed to invoke the [=Web Authentication API=], specify the <{iframe/allow}> attribute on the <{iframe}> element and include the <code><a data-lt="publickey-credentials-feature">publickey-credentials</a></code> feature-identifier token in the <{iframe/allow}> attribute's value.




# WebAuthn <dfn>Authenticator Model</dfn> # {#sctn-authenticator-model}

[[#sctn-api|The Web Authentication API]] implies a specific abstract functional model for a [=[WAA]=]. This section
describes that [=authenticator model=].

[=Client platforms=] MAY implement and expose this abstract model in any way desired. However, the behavior of the client's Web
Authentication API implementation, when operating on the authenticators supported by that [=client platform=], MUST be indistinguishable
from the behavior specified in [[#sctn-api]].

Note: [[!FIDO-CTAP]] is an example of a concrete instantiation of this model, but it is one in which there are differences in the data it returns and those expected by the [[#sctn-api|WebAuthn API]]'s algorithms. The CTAP2 response messages are CBOR maps constructed using integer keys rather than the string keys defined in this specification for the same objects. The [=client=] is expected to perform any needed transformations on such data. The [[!FIDO-CTAP]] specification details the mapping between CTAP2 integer keys and WebAuthn string keys, in section [=§6.2. Responses=].

For authenticators, this model defines the logical operations that they MUST support, and the data formats that they expose to
the client and the [=[WRP]=]. However, it does not define the details of how authenticators communicate with the [=client device=],
unless they are necessary for interoperability with [=[RPS]=]. For instance, this abstract model does not define protocols for
connecting authenticators to clients over transports such as USB or NFC. Similarly, this abstract model does not define specific
error codes or methods of returning them; however, it does define error behavior in terms of the needs of the client. Therefore,
specific error codes are mentioned as a means of showing which error conditions MUST be distinguishable (or not) from each other
in order to enable a compliant and secure client implementation.

[=[RPS]=] may influence authenticator selection, if they deem necessary, by stipulating various authenticator characteristics
when [[#sctn-createCredential|creating credentials]] and/or when [[#sctn-getAssertion|generating assertions]], through use of
[[#dictionary-makecredentialoptions|credential creation options]] or [[#dictionary-assertion-options|assertion generation options]],
respectively. The algorithms underlying the [[#sctn-api|WebAuthn API]] marshal these options and pass them to the applicable
[[#sctn-authenticator-ops|authenticator operations]] defined below.

In this abstract model, the authenticator provides key management and cryptographic signatures. It can be embedded in the
WebAuthn client or housed in a separate device entirely. The authenticator itself can contain a cryptographic module which
operates at a higher security level than the rest of the authenticator. This is particularly important for authenticators that
are embedded in the WebAuthn client, as in those cases this cryptographic module (which may, for example, be a TPM) could be
considered more trustworthy than the rest of the authenticator.

Each authenticator stores a <dfn for=authenticator>credentials map</dfn>, a [=map=] from ([=rpId=], [[=userHandle=]]) to
[=public key credential source=].

Additionally, each authenticator has an AAGUID, which is a 128-bit identifier indicating the type (e.g. make and model) of the
authenticator. The AAGUID MUST be chosen by the manufacturer to be identical across all substantially identical authenticators
made by that manufacturer, and different (with high probability) from the AAGUIDs of all other types of authenticators.
The AAGUID for a given type of authenticator SHOULD be randomly generated to ensure this. The [=[RP]=] MAY use the AAGUID to infer certain
properties of the authenticator, such as certification level and strength of key protection, using information from other sources.

The primary function of the authenticator is to provide [=WebAuthn signatures=], which are bound to various contextual data. These
data are observed and added at different levels of the stack as a signature request passes from the server to the
authenticator. In verifying a signature, the server checks these bindings against expected values. These contextual bindings
are divided in two: Those added by the [=[RP]=] or the client, referred to as [=client data=]; and those added by the authenticator,
referred to as the [=authenticator data=]. The authenticator signs over the [=client data=], but is otherwise not interested in
its contents. To save bandwidth and processing requirements on the authenticator, the client hashes the [=client data=] and
sends only the result to the authenticator. The authenticator signs over the combination of the
[=hash of the serialized client data=], and its own [=authenticator data=].

The goals of this design can be summarized as follows.

- The scheme for generating signatures should accommodate cases where the link between the [=client device=] and authenticator
    is very limited, in bandwidth and/or latency. Examples include Bluetooth Low Energy and Near-Field Communication.

- The data processed by the authenticator should be small and easy to interpret in low-level code. In particular, authenticators
    should not have to parse high-level encodings such as JSON.

- Both the [=client=] and the authenticator should have the flexibility to add contextual bindings as needed.

- The design aims to reuse as much as possible of existing encoding formats in order to aid adoption and implementation.

Authenticators produce cryptographic signatures for two distinct purposes:
1. An <dfn>attestation signature</dfn> is produced when a new [=public key credential=] is created via an
    [=authenticatorMakeCredential=] operation. An [=attestation signature=] provides cryptographic
    proof of certain properties of the [=authenticator=] and the credential. For instance, an [=attestation signature=]
    asserts the [=authenticator=] type (as denoted by its AAGUID) and the [=credential public key=]. The [=attestation
    signature=] is signed by an [=attestation private key=], which is chosen depending on the type of [=attestation=] desired.
    For more details on [=attestation=], see [[#sctn-attestation]].
2. An <dfn>assertion signature</dfn> is produced when the [=authenticatorGetAssertion=] method is invoked. It represents an
    assertion by the [=authenticator=] that the user has [=user consent|consented=] to a specific transaction, such as logging
    in, or completing a purchase. Thus, an [=assertion signature=] asserts that the [=authenticator=] possessing a particular
    [=credential private key=] has established, to the best of its ability, that the user requesting this transaction is the
    same user who [=user consent|consented=] to creating that particular [=public key credential=]. It also asserts additional
    information, termed [=client data=], that may be useful to the caller, such as the means by which [=user consent=] was
    provided, and the prompt shown to the user by the [=authenticator=]. The [=assertion signature=] format is illustrated in
    [Figure 4, below](#fig-signature).

The term <dfn>WebAuthn signature</dfn> refers to both [=attestation signatures=] and [=assertion signatures=].
The formats of these signatures, as well as the procedures for generating them, are specified below.

## Authenticator Data ## {#sctn-authenticator-data}

The <dfn>authenticator data</dfn> structure encodes contextual bindings made by the [=authenticator=]. These bindings are
controlled by the authenticator itself, and derive their trust from the [=[WRP]=]'s assessment of the security properties of the
authenticator. In one extreme case, the authenticator may be embedded in the client, and its bindings may be no more trustworthy
than the [=client data=]. At the other extreme, the authenticator may be a discrete entity with high-security hardware and
software, connected to the client over a secure channel. In both cases, the [=[RP]=] receives the [=authenticator data=] in the same
format, and uses its knowledge of the authenticator to make trust decisions.

The [=authenticator data=] has a compact but extensible encoding. This is desired since authenticators can be devices with
limited capabilities and low power requirements, with much simpler software stacks than the [=client platform=].

The [=authenticator data=] structure is a byte array of 37 bytes or more,
laid out as shown in <a href="#table-authData">Table <span class="table-ref-following"/></a>.


<figure id="table-authData" class="table">
    <table class="complex data longlastcol">
        <tr>
            <th>Name</th>
            <th>Length (in bytes)</th>
            <th>Description</th>
        </tr>
        <tr>
            <td><dfn>rpIdHash</dfn></td>
            <td>32</td>
            <td>
                SHA-256 hash of the [=RP ID=] the [=public key credential|credential=] is [=scoped=] to.
            </td>
        </tr>
        <tr>
            <td><dfn>flags</dfn></td>
            <td>1</td>
            <td>
                Flags (bit 0 is the least significant bit):
                - Bit 0: [=User Present=] ([=UP=]) result.
                    - `1` means the user is [=user present|present=].
                    - `0` means the user is not [=user present|present=].
                - Bit 1: Reserved for future use (`RFU1`).
                - Bit 2: [=User Verified=] ([=UV=]) result.
                    - `1` means the user is [=user verified|verified=].
                    - `0` means the user is not [=user verified|verified=].
                - Bits 3-5: Reserved for future use (`RFU2`).
                - Bit 6: [=Attested credential data=] included (`AT`).
                    - Indicates whether the authenticator added [=attested credential data=].
                - Bit 7: Extension data included (`ED`).
                    - Indicates if the [=authenticator data=] has [=authDataExtensions|extensions=].
            </td>
        </tr>
        <tr>
            <td><dfn>signCount</dfn></td>
            <td>4</td>
            <td>[=Signature counter=], 32-bit unsigned big-endian integer.</td>
        </tr>
        <tr>
            <td><dfn>attestedCredentialData</dfn></td>
            <td>variable (if present)</td>
            <td>
                [=attested credential data=] (if present). See [[#sctn-attested-credential-data]] for details. Its length depends on
                the [=credentialIdLength|length=] of the [=credentialId|credential ID=] and [=credentialPublicKey|credential public
                key=] being attested.
            </td>
        </tr>
        <tr>
            <td><dfn lt="authDataExtensions">extensions</dfn></td>
            <td>variable (if present)</td>
            <td>
                Extension-defined [=authenticator data=]. This is a [=CBOR=] [[!RFC7049]] map with [=extension identifiers=] as keys,
                and [=authenticator extension outputs=] as values. See [[#sctn-extensions]] for details.
            </td>
        </tr>
    </table>
    <figcaption>
        [=Authenticator data=] layout. The names in the Name column are only for reference within this document, and are not
        present in the actual representation of the [=authenticator data=].
    </figcaption>
</figure>

The [=RP ID=] is originally received from the [=client=] when the credential is created, and again when an [=assertion=] is generated.
However, it differs from other [=client data=] in some important ways. First, unlike the [=client data=], the [=RP ID=] of a
credential does not change between operations but instead remains the same for the lifetime of that credential. Secondly, it is
validated by the authenticator during the [=authenticatorGetAssertion=] operation, by verifying that the [=RP ID=] that
the requested [=public key credential|credential=] is [=scoped=] to exactly matches the [=RP ID=] supplied by the [=client=].

[=Authenticators=] <dfn for="authenticator data">perform the following steps to generate an [=authenticator data=] structure</dfn>:

- Hash [=RP ID=] using SHA-256 to generate the [=rpIdHash=].

- The `UP` [=flag=] SHALL be set if and only if the authenticator performed a [=test of user presence=].
    The `UV` [=flag=] SHALL be set if and only if the authenticator performed [=user verification=].
    The `RFU` bits SHALL be set to zero.

    Note: If the authenticator performed both a [=test of user presence=] and [=user verification=],
    possibly combined in a single [=authorization gesture=],
    then the authenticator will set both the `UP` [=flag=] and the `UV` [=flag=].

- For [=attestation signatures=], the authenticator MUST set the AT [=flag=] and include the <code>[=attestedCredentialData=]</code>.
    For [=assertion signatures=], the AT [=flag=] MUST NOT be set and the <code>[=attestedCredentialData=]</code> MUST NOT be included.

- If the authenticator does not include any [=authDataExtensions|extension data=], it MUST set the `ED` [=flag=] to zero, and to one if
    [=authDataExtensions|extension data=] is included.

<a href="#fig-authData">Figure <span class="figure-num-following"/></a> shows a visual representation of the [=authenticator data=] structure.

<figure id="fig-authData">
    <img src="images/fido-signature-formats-figure1.svg"/>
    <figcaption>[=Authenticator data=] layout.</figcaption>
</figure>

<div class="note">
    Note: [=authenticator data=] describes its own length: If the AT and ED [=flags=] are not set, it is always 37 bytes long.
    The [=attested credential data=] (which is only present if the AT [=flag=] is set) describes its own length. If the ED [=flag=] is set, then the total length is 37 bytes plus the length of the [=attested credential data=] (if the AT [=flag=] is set), plus the length of the [=authDataExtensions|extensions=] output (a [=CBOR=] map) that
    follows.

    Determining [=attested credential data=]'s length, which is variable, involves determining <code>[=credentialPublicKey=]</code>'s beginning location given the preceding <code>[=credentialid|credentialId=]</code>'s [=credentialidlength|length=], and then determining the <code>[=credentialPublicKey=]</code>'s length (see also [=Section 7=] of [[!RFC8152]]).
</div>

### <dfn>Signature Counter</dfn> Considerations ### {#sctn-sign-counter}

Authenticators SHOULD implement a [=signature counter=] feature. The [=signature counter=] is incremented for each successful
[=authenticatorGetAssertion=] operation by some positive value, and its value is returned to the [=[WRP]=] within the
[=authenticator data=]. The [=signature counter=]'s purpose is to aid [=[RPS]=] in detecting cloned authenticators. Clone
detection is more important for authenticators with limited protection measures.

A [=[RP]=] stores the [=signature counter=] of the most recent [=authenticatorGetAssertion=] operation. Upon a new
[=authenticatorGetAssertion=] operation, the [=[RP]=] compares the stored [=signature counter=] value with the new
<code>[=signCount=]</code> value returned in the assertion's [=authenticator data=].  If this new <code>[=signCount=]</code> value is less than or equal to the stored value, a cloned authenticator may exist, or the authenticator may be malfunctioning.

Detecting a [=signature counter=]  mismatch does not indicate whether the current operation was performed by a cloned authenticator or the original authenticator.  [=[RPS]=] should address this situation appropriately relative to their individual situations, i.e., their risk tolerance.

Authenticators:
- SHOULD implement per credential [=signature counters=].  This prevents the
    [=signature counter=] value from being shared between [=[RPS]=] and being possibly employed
    as a correlation handle for the user. Authenticators may implement a global [=signature counter=],
    i.e., on a per-authenticator basis, but this is less privacy-friendly for users.

- SHOULD ensure that the [=signature counter=] value does not
    accidentally decrease  (e.g., due to hardware failures).


### FIDO U2F Signature Format Compatibility ### {#sctn-fido-u2f-sig-format-compat}

The format for [=assertion signatures=], which sign over the concatenation of an [=authenticator data=] structure and the [=hash
of the serialized client data=], are compatible with the FIDO U2F authentication signature format (see [=Section 5.4=] of
[[FIDO-U2F-Message-Formats]]).

This is because the first 37 bytes of the signed data in a FIDO U2F authentication response message constitute a valid
[=authenticator data=] structure, and the remaining 32 bytes are the [=hash of the serialized client data=]. In this
[=authenticator data=] structure, the <code>[=rpIdHash=]</code> is the FIDO U2F [=application parameter=], all
<code>[=flags=]</code> except <code>[=UP=]</code> are always zero, and the <code>[=attestedCredentialData=]</code> and
<code>[=authDataExtensions|extensions=]</code> are never present. FIDO U2F authentication signatures can therefore be verified by
the same procedure as other [=assertion signatures=] generated by the [=authenticatorMakeCredential=] operation.


## Authenticator Taxonomy ## {#sctn-authenticator-taxonomy}

Many use cases are dependent on the capabilities of the [=authenticator=] used.
This section defines some terminology for those capabilities, their most important combinations,
and which use cases those combinations enable.

For example:

- When authenticating for the first time on a particular [=client device=], a [=roaming authenticator=] is typically needed
    since the user doesn't yet have a [=platform credential=] on that [=client device=].
- For subsequent re-authentication on the same [=client device=], a [=platform authenticator=] is likely the most convenient
    since it's built directly into the [=client device=] rather than being a separate device that the user may have to locate.
- For [=second-factor=] authentication in addition to a traditional username and password, any [=authenticator=] can be used.
- Passwordless [=multi-factor=] authentication requires an [=authenticator=]
    capable of [=user verification=], and in some cases also [=resident credential capable=].
- A laptop computer might support connecting to [=roaming authenticators=] via USB and Bluetooth,
    while a mobile phone might only support NFC.

The above examples illustrate the the primary <dfn>authenticator type</dfn> characteristics:

- Whether the [=authenticator=] is a [=roaming authenticator|roaming=] or [=platform authenticator|platform=] authenticator
    &mdash; the [=authenticator attachment modality=].
    A [=roaming authenticator=] can support one or more [[#enum-transport|transports]] for communicating with the [=client=].
- Whether the authenticator is capable of [=user verification=] &mdash; the [=authentication factor capability=].
- Whether the authenticator is [=resident credential capable=] &mdash; the [=credential storage modality=].

These characteristics are independent and may in theory be combined in any way,
but <a href="#table-authenticatorTypes">Table <span class="table-ref-following"/></a>
lists and names some [=authenticator types=] of particular interest.


<figure id="table-authenticatorTypes" class="table">
    <table class="data">
        <thead>
            <tr>
                <th> [=Authenticator Type=] </th>
                <th> [=Authenticator Attachment Modality=] </th>
                <th> [=Credential Storage Modality=] </th>
                <th> [=Authentication Factor Capability=] </th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <th> <dfn>Second-factor platform authenticator</dfn> </th>
                <td> [=platform attachment|platform=] </td>
                <td> Either </td>
                <td> [=Single-factor capable=] </td>
            </tr>
            <tr>
                <th> <dfn>User-verifying platform authenticator</dfn> </th>
                <td> [=platform attachment|platform=] </td>
                <td> Either </td>
                <td> [=Multi-factor capable=] </td>
            </tr>
            <tr>
                <th> <dfn>Second-factor roaming authenticator</dfn> </th>
                <td> [=cross-platform attachment|cross-platform=] </td>
                <td> [=server-side credential storage modality|Server-side storage=] </td>
                <td> [=Single-factor capable=] </td>
            </tr>
            <tr>
                <th> <dfn>First-factor roaming authenticator</dfn> </th>
                <td> [=cross-platform attachment|cross-platform=] </td>
                <td> [=client-side credential storage modality|Client-side storage=] </td>
                <td> [=Multi-factor capable=] </td>
            </tr>
        </tbody>
    </table>
    <figcaption>
        Definitions of names for some [=authenticator types=].
    </figcaption>
</figure>

A [=second-factor platform authenticator=] is convenient to use for re-authentication on the same [=client device=],
and can be used to add an extra layer of security both when initiating a new session and when resuming an existing session.
A [=second-factor roaming authenticator=] is more likely to be used
to authenticate on a particular [=client device=] for the first time,
or on a [=client device=] shared between multiple users.

[=User-verifying platform authenticators=] and [=first-factor roaming authenticators=]
enable passwordless [=multi-factor=] authentication.
In addition to the proof of possession of the [=credential private key=],
these authenticators support [=user verification=] as a second [=authentication factor=],
typically a PIN or [=biometric recognition=].
The [=authenticator=] can thus act as two kinds of [=authentication factor=],
which enables [=multi-factor=] authentication while eliminating the need to share a password with the [=[RP]=].

The four combinations not named in <a href="#table-authenticatorTypes">Table <span class="table-ref-previous"/></a>
have less distinguished use cases:


- The [=credential storage modality=] is less relevant for a [=platform authenticator=] than for a [=roaming authenticator=],
    since users using a [=platform authenticator=] can typically be identified by a session cookie or the like
    (i.e., ambient credentials).
- A [=roaming authenticator=] that is [=resident credential capable=] but not [=multi-factor capable=]
    can be used for [=single-factor=] authentication without a username,
    where the user is automatically identified by the [=user handle=]
    and possession of the [=credential private key=] is used as the only [=authentication factor=].
    This can be useful in some situations, but makes the user particularly vulnerable to theft of the [=authenticator=].
- A [=roaming authenticator=] that is [=multi-factor capable=] but not [=resident credential capable=]
    can be used for [=multi-factor=] authentication, but requires the user to be identified first
    which risks leaking [PII]; see [[#sctn-credential-id-privacy-leak]].

The following subsections define the aspects [=authenticator attachment modality=],
[=credential storage modality=] and [=authentication factor capability=] in more depth.


### <dfn>Authenticator Attachment Modality</dfn> ### {#sctn-authenticator-attachment-modality}

[=Clients=] can communicate with [=authenticators=] using a variety of mechanisms. For example, a [=client=] MAY use a
[=client device=]-specific API to communicate with an [=authenticator=] which is physically bound to a [=client device=]. On the other hand, a
[=client=] can use a variety of standardized cross-platform transport protocols such as Bluetooth (see [[#enum-transport]]) to discover
and communicate with [=cross-platform attachment|cross-platform attached=] [=authenticators=]. We refer to [=authenticators=] that
are part of the [=client device=] as <dfn>platform authenticators</dfn>, while those that are reachable via cross-platform
transport protocols are referred to as <dfn>roaming authenticators</dfn>.

- A [=platform authenticator=] is attached using a [=client device=]-specific transport, called <dfn>platform attachment</dfn>, and is usually not removable from the [=client
    device=]. A [=public key credential=] [=bound credential|bound=] to a [=platform authenticator=] is called a <dfn>platform credential</dfn>.

- A [=roaming authenticator=] is attached using cross-platform transports, called <dfn>cross-platform attachment</dfn>. Authenticators of this class are removable from, and
    can "roam" between, [=client devices=]. A [=public key credential=] [=bound credential|bound=] to a [=roaming authenticator=] is called a <dfn>roaming
    credential</dfn>.

Some [=platform authenticators=] could possibly also act as [=roaming authenticators=] depending on context. For example, a
[=platform authenticator=] integrated into a mobile device could make itself available as a [=roaming authenticator=] via
Bluetooth.
In this case [=clients=] running on the mobile device would recognise the authenticator as a [=platform authenticator=],
while [=clients=] running on a different [=client device=] and communicating with the same authenticator via Bluetooth
would recognize it as a [=roaming authenticator=].

The primary use case for [=platform authenticators=] is to register a particular [=client device=] as a "trusted device",
so the [=client device=] itself acts as a [=something you have=] [=authentication factor=] for future [=authentication=].
This gives the user the convenience benefit
of not needing a [=roaming authenticator=] for future [=authentication ceremonies=], e.g., the user will not have to dig around in
their pocket for their key fob or phone.

Use cases for [=roaming authenticators=] include:
[=authentication|authenticating=] on a new [=client device=] for the first time,
on rarely used [=client devices=], [=client devices=] shared between multiple users,
or [=client devices=] that do not include a [=platform authenticator=];
and when policy or preference dictates that the [=authenticator=] be kept separate from the [=client devices=] it is used with.
A [=roaming authenticator=] can also be used to hold
backup [=public key credential|credentials=] in case another [=authenticator=] is lost.


### Credential Storage Modality ### {#sctn-credential-storage-modality}

An [=authenticator=] can store a [=public key credential source=] in one of two ways:

 1. In persistent storage embedded in the [=authenticator=], [=client=] or [=client device=], e.g., in a secure element.
    This is a technical requirement for a [=client-side-resident public key credential source=].

 1. By encrypting (i.e., wrapping) the [=credential private key=] such that only this [=authenticator=] can decrypt (i.e., unwrap) it and letting the resulting
    ciphertext be the [=credential ID=] for the [=public key credential source=]. The [=credential ID=] is stored by the [=[RP]=]
    and returned to the [=authenticator=] via the {{PublicKeyCredentialRequestOptions/allowCredentials}} option of
    {{CredentialsContainer/get()}}, which allows the [=authenticator=] to decrypt and use the [=credential private key=].

    This enables the [=authenticator=] to have unlimited storage capacity for [=credential private keys=], since the encrypted
    [=credential private keys=] are stored by the [=[RP]=] instead of by the [=authenticator=] - but it means that a
    [=credential=] stored in this way must be retrieved from the [=[RP]=] before the [=authenticator=] can use it.

Which of these storage strategies an [=authenticator=] supports defines the [=authenticator=]'s <dfn>credential storage
modality</dfn> as follows:

- An [=authenticator=] has the <dfn>client-side credential storage modality</dfn> if it supports [=client-side-resident public key
    credential sources=]. An [=authenticator=] with [=client-side credential storage modality=] is also called <dfn>resident
    credential capable</dfn>.

- An [=authenticator=] has the <dfn>server-side credential storage modality</dfn> if it does not have the [=client-side credential storage
    modality=], i.e., it only supports storing [=credential private keys=] as a ciphertext in the [=credential ID=].

Note that a [=resident credential capable=] [=authenticator=] MAY support both storage strategies. In this case, the [=authenticator=] MAY
at its discretion use different storage strategies for different [=public key credential|credentials=], though subject to the
{{AuthenticatorSelectionCriteria/residentKey}} or {{AuthenticatorSelectionCriteria/requireResidentKey}} options of
{{CredentialsContainer/create()}}.


### <dfn>Authentication Factor Capability</dfn> ### {#sctn-authentication-factor-capability}

There are three broad classes of [=authentication factors=] that can be used to prove an identity during an [=authentication
ceremony=]: [=something you have=], [=something you know=] and [=something you are=]. Examples include a physical key, a password,
and a fingerprint, respectively.

All [=[WAA]s=] belong to the [=something you have=] class, but an [=authenticator=] that supports [=user
verification=] can also act as one or two additional kinds of [=authentication factor=]. For example, if the [=authenticator=] can
verify a PIN, the PIN is [=something you know=], and a [=biometric authenticator=] can verify [=something you are=]. Therefore, an
[=authenticator=] that supports [=user verification=] is <dfn>multi-factor capable</dfn>. Conversely, an [=authenticator=] that is
not [=multi-factor capable=] is <dfn>single-factor capable</dfn>. Note that a single [=multi-factor capable=] [=authenticator=]
could support several modes of [=user verification=], meaning it could act as all three kinds of [=authentication factor=].

Although [=user verification=] is performed locally on the [=authenticator=] and not by the [=[RP]=], the [=authenticator=]
indicates if [=user verification=] was performed by setting the [=UV=] [=flag=] in the signed response returned to the [=[RP]=].
The [=[RP]=] can therefore use the [=UV=] flag to verify that additional [=authentication factors=] were used in a
[=registration=] or [=authentication ceremony=]. The authenticity of the [=UV=] [=flag=] can in turn be assessed by inspecting the
[=authenticator=]'s [=attestation statement=].


## <dfn>Authenticator Operations</dfn> ## {#sctn-authenticator-ops}

A [=[WAC]=] MUST connect to an authenticator in order to invoke any of the operations of that authenticator. This connection
defines an <dfn>authenticator session</dfn>. An authenticator must maintain isolation between sessions. It may do this by only allowing one
session to exist at any particular time, or by providing more complicated session management.

The following operations can be invoked by the client in an authenticator session.


### Lookup Credential Source by Credential ID Algorithm ### {#sctn-op-lookup-credsource-by-credid}

The result of <dfn for="credential id">looking up</dfn> a [=credential id=] |credentialId| in an [=authenticator=]
|authenticator| is the result of the following algorithm:
1. If |authenticator| can decrypt |credentialId| into a [=public key credential source=] |credSource|:
    1. Set |credSource|.[=public key credential source/id=] to |credentialId|.
    1. Return |credSource|.
1. [=map/For each=] [=public key credential source=] |credSource| of |authenticator|'s [=credentials map=]:
    1. If |credSource|.[=public key credential source/id=] is |credentialId|, return |credSource|.
1. Return `null`.


### The <dfn>authenticatorMakeCredential</dfn> Operation ### {#sctn-op-make-cred}

It takes the following input parameters:

<!-- @@EDITOR-ANCHOR-01B: KEEP THIS LIST SYNC'D WITH THE LIST UP AT @@EDITOR-ANCHOR-01A -->
: |hash|
:: The [=hash of the serialized client data=], provided by the client.
: |rpEntity|
:: The [=[RP]=]'s {{PublicKeyCredentialRpEntity}}.
: |userEntity|
:: The user account's {{PublicKeyCredentialUserEntity}}, containing the [=user handle=] given by the [=[RP]=].
: |requireResidentKey|
:: The [=effective resident key requirement for credential creation=], a Boolean value determined by the [=client=].
: |requireUserPresence|
:: The constant Boolean value [TRUE].
    It is included here as a pseudo-parameter to simplify applying this abstract authenticator model to implementations that may
    wish to make a [=test of user presence=] optional although WebAuthn does not.
: |requireUserVerification|
:: The [=effective user verification requirement for credential creation=], a Boolean value determined by the [=client=].
: |credTypesAndPubKeyAlgs|
:: A sequence of pairs of {{PublicKeyCredentialType}} and public key algorithms ({{COSEAlgorithmIdentifier}}) requested by the
    [=[RP]=]. This sequence is ordered from most preferred to least preferred. The [=authenticator=] makes a best-effort to create the most
    preferred credential that it can.
: |excludeCredentialDescriptorList|
:: An OPTIONAL list of {{PublicKeyCredentialDescriptor}} objects provided by the [=[RP]=] with the intention that, if any of
    these are known to the authenticator, it SHOULD NOT create a new credential. |excludeCredentialDescriptorList| contains a
    list of known credentials.
: |extensions|
:: A [=CBOR=] [=map=] from [=extension identifiers=] to their [=authenticator extension inputs=], created by the [=client=] based on
    the extensions requested by the [=[RP]=], if any.

Note: Before performing this operation, all other operations in progress in the [=authenticator session=] MUST be aborted by
running the [=authenticatorCancel=] operation.

When this operation is invoked, the [=authenticator=] MUST perform the following procedure:
1. Check if all the supplied parameters are syntactically well-formed and of the correct length. If not, return an error code
    equivalent to "{{UnknownError}}" and terminate the operation.
1. Check if at least one of the specified combinations of {{PublicKeyCredentialType}} and cryptographic parameters in
    |credTypesAndPubKeyAlgs| is supported.
    If not, return an error code equivalent to "{{NotSupportedError}}" and terminate the operation.

1. [=list/For each=] |descriptor| of |excludeCredentialDescriptorList|:

    1.  If [=credential id/looking up=] <code>|descriptor|.{{PublicKeyCredentialDescriptor/id}}</code> in this authenticator
        returns non-null, and the returned [=list/item=]'s [=RP ID=] and [=type=] match
        <code>|rpEntity|.{{PublicKeyCredentialRpEntity/id}}</code> and
        <code>|excludeCredentialDescriptorList|.{{PublicKeyCredentialDescriptor/type}}</code> respectively,
        then collect an [=authorization gesture=] confirming [=user
        consent=] for creating a new credential. The [=authorization gesture=] MUST include a [=test
        of user presence=]. If the user
        <dl class="switch">
            :   confirms consent to create a new credential
            ::  return an error code equivalent to "{{InvalidStateError}}" and terminate the operation.

            :   does not consent to create a new credential
            ::  return an error code equivalent to "{{NotAllowedError}}" and terminate the operation.
        </dl>

        Note: The purpose of this [=authorization gesture=] is not to proceed with creating a credential,
        but for privacy reasons to authorize disclosure of the fact that
        <code>|descriptor|.{{PublicKeyCredentialDescriptor/id}}</code> is [=bound credential|bound=] to this [=authenticator=].
        If the user consents, the [=client=] and [=[RP]=] can detect this and guide the user to use a different [=authenticator=].
        If the user does not consent,
        the [=authenticator=] does not reveal that <code>|descriptor|.{{PublicKeyCredentialDescriptor/id}}</code>
        is [=bound credential|bound=] to it,
        and responds as if the user simply declined consent to create a credential.

1. If |requireResidentKey| is [TRUE] and the authenticator cannot store a [=client-side-resident public key credential source=],
    return an error code equivalent to "{{ConstraintError}}" and terminate the operation.
1. If |requireUserVerification| is [TRUE] and the authenticator cannot perform [=user verification=], return an error code
    equivalent to "{{ConstraintError}}" and terminate the operation.

<!-- Note: this next step is actually a top-level step, but bikeshed wanted it indented this much in order to render it as
a numbered step. If outdented, it (today) is rendered as a bullet in the midst of a numbered list :-/
-->
    <li id='op-makecred-step-user-consent'>
        Collect an [=authorization gesture=] confirming [=user consent=] for creating a new credential.
        The prompt for the [=authorization gesture=] is shown by the
        authenticator if it has its own output capability, or by the user agent otherwise. The prompt SHOULD display
        <code>|rpEntity|.{{PublicKeyCredentialRpEntity/id}}</code>, <code>|rpEntity|.{{PublicKeyCredentialEntity/name}}</code>,
        <code>|userEntity|.{{PublicKeyCredentialEntity/name}}</code> and
        <code>|userEntity|.{{PublicKeyCredentialUserEntity/displayName}}</code>, if possible.

        If |requireUserVerification| is [TRUE], the [=authorization gesture=] MUST include [=user verification=].

        If |requireUserPresence| is [TRUE], the [=authorization gesture=] MUST include a [=test of user presence=].

        If the user does not [=user consent|consent=] or if [=user verification=] fails, return an error code equivalent to
        "{{NotAllowedError}}" and terminate the operation.
    </li>

1. Once the [=authorization gesture=] has been completed and [=user consent=] has been obtained, generate a new credential object:
    1. Let (|publicKey|, |privateKey|) be a new pair of cryptographic keys using the combination of {{PublicKeyCredentialType}}
        and cryptographic parameters represented by the first [=list/item=] in |credTypesAndPubKeyAlgs| that is supported by
        this authenticator.
    1. Let |userHandle| be <code>|userEntity|.{{PublicKeyCredentialUserEntity/id}}</code>.
    1. Let |credentialSource| be a new [=public key credential source=] with the fields:
        <dl link-for="public key credential source">
            : [=type=]
            :: {{PublicKeyCredentialType/public-key}}.
            : [=privateKey=]
            :: |privateKey|
            : [=rpId=]
            :: <code>|rpEntity|.{{PublicKeyCredentialRpEntity/id}}</code>
            : [=userHandle=]
            :: |userHandle|
            : [=otherUI=]
            :: Any other information the authenticator chooses to include.
        </dl>
    1. If |requireResidentKey| is [TRUE] or the authenticator chooses to create a [=client-side-resident public key credential source=]:
        1. Let |credentialId| be a new [=credential id=].
        1. Set |credentialSource|.[=public key credential source/id=] to |credentialId|.
        1. Let |credentials| be this authenticator's [=credentials map=].
        1. [=map/Set=] |credentials|[(<code>|rpEntity|.{{PublicKeyCredentialRpEntity/id}}</code>, |userHandle|)] to |credentialSource|.
    1. Otherwise:
        1. Let |credentialId| be the result of serializing and encrypting |credentialSource| so that only this authenticator can
            decrypt it.
1. If any error occurred while creating the new credential object, return an error code equivalent to "{{UnknownError}}" and
    terminate the operation.
1. Let |processedExtensions| be the result of [=authenticator extension processing=] [=map/for each=] supported [=extension
    identifier=] → [=authenticator extension input=] in |extensions|.
1. If the [=authenticator=] supports:
    <dl class="switch">
        :  a global [=signature counter=]
        ::  Use the global [=signature counter=]'s actual value when generating
              [=authenticator data=].
        : a per credential [=signature counter=]
        :: allocate the counter, associate it with the new credential, and initialize the counter value as zero.

        : no [=signature counter=]
        :: let the [=signature counter=] value for the new credential be constant at zero.
    </dl>

1. Let |attestedCredentialData| be the [=attested credential data=] byte array including the |credentialId| and |publicKey|.
1. Let |authenticatorData| [=perform the following steps to generate an authenticator data structure|be the byte array=] specified in [[#sctn-authenticator-data]], including |attestedCredentialData| as the
    <code>[=attestedCredentialData=]</code> and |processedExtensions|, if any, as the
    <code>[=authDataExtensions|extensions=]</code>.
1. Return the [=attestation object=] for the new credential created by the procedure specified in
    [[#sctn-generating-an-attestation-object]] using an authenticator-chosen [=attestation statement format=], |authenticatorData|,
    and |hash|. For more details on attestation, see [[#sctn-attestation]].

On successful completion of this operation, the authenticator returns the [=attestation object=] to the client.


### The <dfn>authenticatorGetAssertion</dfn> Operation ### {#sctn-op-get-assertion}

It takes the following input parameters:

: |rpId|
:: The caller's [=RP ID=], as <a href='#GetAssn-DetermineRpId'>determined</a> by the user agent and the client.
: |hash|
:: The [=hash of the serialized client data=], provided by the client.
: |allowCredentialDescriptorList|
:: An OPTIONAL [=list=] of {{PublicKeyCredentialDescriptor}}s describing credentials acceptable to the [=[RP]=] (possibly filtered
    by the client), if any.
: |requireUserPresence|
:: The constant Boolean value [TRUE].
    It is included here as a pseudo-parameter to simplify applying this abstract authenticator model to implementations that may
    wish to make a [=test of user presence=] optional although WebAuthn does not.
: |requireUserVerification|
:: The [=effective user verification requirement for assertion=], a Boolean value provided by the client.
: |extensions|
:: A [=CBOR=] [=map=] from [=extension identifiers=] to their [=authenticator extension inputs=], created by the client based on
    the extensions requested by the [=[RP]=], if any.

Note: Before performing this operation, all other operations in progress in the [=authenticator session=] MUST be aborted by running the [=authenticatorCancel=] operation.

When this method is invoked, the [=authenticator=] MUST perform the following procedure:

1. Check if all the supplied parameters are syntactically well-formed and of the correct length. If not, return an error code
    equivalent to "{{UnknownError}}" and terminate the operation.
1. Let |credentialOptions| be a new empty [=set=] of [=public key credential sources=].
1. If |allowCredentialDescriptorList| was supplied, then [=list/for each=] |descriptor| of |allowCredentialDescriptorList|:
    1. Let |credSource| be the result of [=looking up=] <code>|descriptor|.{{PublicKeyCredentialDescriptor/id}}</code> in this
        authenticator.
    1. If |credSource| is not `null`, [=set/append=] it to |credentialOptions|.
1. Otherwise (|allowCredentialDescriptorList| was not supplied), [=map/for each=] <var ignore>key</var> → |credSource| of this
    authenticator's [=credentials map=], [=set/append=] |credSource| to |credentialOptions|.
1. [=list/Remove=] any items from |credentialOptions| whose [=public key credential source/rpId=] is not equal to
    |rpId|.
1. If |credentialOptions| is now empty, return an error code equivalent to "{{NotAllowedError}}" and terminate the operation.

1. Prompt the user to select a [=public key credential source=] |selectedCredential| from |credentialOptions|.
    Collect an [=authorization gesture=] confirming [=user consent=] for using |selectedCredential|.
    The prompt for the [=authorization gesture=] may be shown
    by the [=authenticator=] if it has its own output capability, or by the user agent otherwise.

    If |requireUserVerification| is [TRUE], the [=authorization gesture=] MUST include [=user verification=].

    If |requireUserPresence| is [TRUE], the [=authorization gesture=] MUST include a
        [=test of user presence=].

    If the user does not [=user consent|consent=], return an error code equivalent to
    "{{NotAllowedError}}" and terminate the operation.

1. Let |processedExtensions| be the result of [=authenticator extension processing=] [=map/for each=] supported [=extension
    identifier=] → [=authenticator extension input=] in |extensions|.
1. Increment the credential associated
    [=signature counter=] or the global [=signature counter=] value, depending on
    which approach is implemented by the [=authenticator=], by some positive value.
    If the [=authenticator=] does not implement a [=signature counter=], let the [=signature counter=] value remain constant at
    zero.
1. Let |authenticatorData| [=perform the following steps to generate an authenticator data structure|be the byte array=]
    specified in [[#sctn-authenticator-data]] including |processedExtensions|, if any, as
    the <code>[=authDataExtensions|extensions=]</code> and excluding <code>[=attestedCredentialData=]</code>.
1. Let |signature| be the [=assertion signature=] of the concatenation <code>|authenticatorData| || |hash|</code> using the
    [=public key credential source/privateKey=] of |selectedCredential| as shown in <a href="#fig-signature">Figure <span class="figure-num-following"/></a>, below. A simple,
    undelimited
    concatenation is safe to use here because the [=authenticator data=] describes its own length. The [=hash of the serialized
    client data=] (which potentially has a variable length) is always the last element.

    <figure id="fig-signature">
        <img src="images/fido-signature-formats-figure2.svg"/>
        <figcaption>Generating an [=assertion signature=].</figcaption>
    </figure>

1. If any error occurred while generating the [=assertion signature=], return an error code equivalent to "{{UnknownError}}" and
    terminate the operation.

<!-- Note: this next step is actually a top-level step, but bikeshed wanted it indented this much in order to render it as
a numbered step. If outdented, it (today) is rendered as a bullet in the midst of a numbered list :-/
-->
    <li id='authenticatorGetAssertion-return-values'>
        Return to the user agent:
            - |selectedCredential|.[=public key credential source/id=], if either a list of credentials
                (i.e., |allowCredentialDescriptorList|) of length 2 or greater was
                supplied by the client, or no such list was supplied.

                    Note: If, within |allowCredentialDescriptorList|, the client supplied exactly one credential and it was successfully employed, then its
                        [=credential ID=] is not returned since the client already knows it. This saves transmitting these bytes over
                        what may be a constrained connection in what is likely a common case.

            - |authenticatorData|
            - |signature|
            - |selectedCredential|.[=public key credential source/userHandle=]

                    Note: the returned [=public key credential source/userHandle=] value may be `null`, see:
                        [=assertionCreationData/userHandleResult=].
    </li>

If the [=authenticator=] cannot find any [=public key credential|credential=] corresponding to the specified [=[RP]=] that
matches the specified criteria, it terminates the operation and returns an error.


### The <dfn>authenticatorCancel</dfn> Operation ### {#sctn-op-cancel}

This operation takes no input parameters and returns no result.

When this operation is invoked by the client in an [=authenticator session=], it has the effect of terminating any
[=authenticatorMakeCredential=] or [=authenticatorGetAssertion=] operation currently in progress in that authenticator
session. The authenticator stops prompting for, or accepting, any user input related to authorizing the canceled operation. The
client ignores any further responses from the authenticator for the canceled operation.

This operation is ignored if it is invoked in an [=authenticator session=] which does not have an [=authenticatorMakeCredential=]
or [=authenticatorGetAssertion=] operation currently in progress.


## String Handling ## {#sctn-strings}

Authenticators may be required to store arbitrary strings chosen by a [=[RP]=], for example the {{PublicKeyCredentialEntity/name}} and {{PublicKeyCredentialUserEntity/displayName}} in a {{PublicKeyCredentialUserEntity}}. Each will have some accommodation for the potentially limited resources available to an [=authenticator=].

If string value truncation is the chosen accommodation then authenticators MAY truncate in order to make the string fit within a length equal or greater than the specified minimum supported length. Such truncation MAY also respect UTF-8 sequence boundaries or [=grapheme cluster=] boundaries [[UTR29]]. This defines the maximum truncation permitted and authenticators MUST NOT truncate further.

For example, in <a href="#fig-stringTruncation">figure <span class="figure-num-following"/></a> the string is 65 bytes long. If truncating to 64 bytes then the final 0x88 byte must be removed purely because of space reasons. Since that leaves a partial UTF-8 sequence the remainder of that sequence may also be removed. Since that leaves a partial [=grapheme cluster=] an authenticator may remove the remainder of that cluster.

<figure id="fig-stringTruncation">
    <img src="images/string-truncation.svg"/>
    <figcaption>The end of a UTF-8 encoded string showing the positions of different truncation boundaries.</figcaption>
</figure>

[=Conforming User Agents=] are responsible for ensuring that the authenticator behaviour observed by [=[RPS]=] conforms to this specification with respect to string handling. For example, if an authenticator is known to behave incorrectly when asked to store large strings, the user agent SHOULD perform the truncation for it in order to maintain the model from the point of view of the [=[RP]=]. User-agents that do this SHOULD truncate at [=grapheme clusters=].

Truncation based on UTF-8 sequences alone may cause a [=grapheme cluster=] to be truncated, but still valid [[UTR29]]. This could make the grapheme cluster render as a different valid glyph instead of removing the glyph entirely.

In addition to that, truncating on byte boundaries alone causes a known issue that user agents should be aware of: if the authenticator is using [[!FIDO-CTAP]] then future messages from the authenticator may contain invalid CBOR since the value is typed as a CBOR string and thus is required to be valid UTF-8. User agents are tasked with handling this to avoid burdening authenticators with understanding character encodings and Unicode character properties. Thus, when dealing with [=authenticators=], user agents SHOULD:

1. Ensure that any strings sent to authenticators are validly encoded.
1. Handle the case where strings have been truncated resulting in an invalid encoding. For example, any partial code point at the end may be dropped or replaced with [U+FFFD](http://unicode.org/cldr/utility/character.jsp?a=FFFD).

## Attestation ## {#sctn-attestation}

[=Authenticators=] SHOULD also provide some form of [=attestation=], if possible.
If an authenticator does, the basic requirement is that the [=authenticator=] can
produce, for each [=credential public key=], an [=attestation statement=] verifiable by the [=[WRP]=]. Typically, this
[=attestation statement=] contains a signature by an [=attestation private key=] over the attested [=credential public key=] and
a challenge, as well as a certificate or similar data providing provenance information for the [=attestation public key=],
enabling the [=[RP]=] to make a trust decision. However, if an [=attestation key pair=] is not available, then the authenticator
MAY either perform [=self attestation=] of the [=credential public key=] with the corresponding [=credential private key=],
or otherwise perform [=None|no attestation=]. All this
information is returned by [=authenticators=] any time a new [=public key credential=] is generated, in the overall form of an
<dfn>attestation object</dfn>. The relationship of the [=attestation object=] with [=authenticator data=] (containing
[=attested credential data=]) and the [=attestation statement=] is illustrated in <a href="#fig-attStructs">figure <span class="figure-num-following"/></a>, below.

If an [=authenticator=] employs [=self attestation=] or [=None|no attestation=], then no provenance information is provided
for the [=[RP]=] to base a trust decision on.
In these cases, the [=authenticator=] provides no guarantees about its operation to the [=[RP]=].

<figure id="fig-attStructs">
    <img src="images/fido-attestation-structures.svg"/>
    <figcaption>[=Attestation object=] layout illustrating the included [=authenticator data=] (containing [=attested credential
    data=]) and the [=attestation statement=].</figcaption>
</figure>
<div class="note">
  This figure illustrates only the `packed` [=attestation statement format=]. Several additional [=attestation statement
  formats=] are defined in [[#sctn-defined-attestation-formats]].
</div>

An important component of the [=attestation object=] is the <dfn>attestation statement</dfn>. This is a specific type of signed
data object, containing statements about a [=public key credential=] itself and the [=authenticator=] that created it. It
contains an [=attestation signature=] created using the key of the attesting authority (except for the case of [=self
attestation=], when it is created using the [=credential private key=]). In order to correctly interpret an [=attestation
statement=], a [=[RP]=] needs to understand these two aspects of [=attestation=]:

1. The <dfn>attestation statement format</dfn> is the manner in which the signature is represented and the various contextual
    bindings are incorporated into the attestation statement by the [=authenticator=]. In other words, this defines the
    syntax of the statement. Various existing components and OS platforms (such as TPMs and the Android OS) have previously defined
    [=attestation statement formats=]. This specification supports a variety of such formats in an extensible way, as defined in
    [[#sctn-attestation-formats]]. The formats themselves are identified by strings, as described in [[#sctn-attstn-fmt-ids]].

2. The <dfn>attestation type</dfn> defines the semantics of [=attestation statements=] and their underlying trust models.
    Specifically, it defines how a [=[RP]=] establishes trust in a particular [=attestation statement=], after verifying that it
    is cryptographically valid. This specification supports a number of [=attestation types=], as described in
    [[#sctn-attestation-types]].

In general, there is no simple mapping between [=attestation statement formats=] and [=attestation types=]. For example, the
"packed" [=attestation statement format=] defined in [[#sctn-packed-attestation]] can be used in conjunction with all [=attestation
types=], while other formats and types have more limited applicability.

The privacy, security and operational characteristics of [=attestation=] depend on:
- The [=attestation type=], which determines the trust model,
- The [=attestation statement format=], which MAY constrain the strength of the [=attestation=] by limiting what can be
    expressed in an [=attestation statement=], and
- The characteristics of the individual [=authenticator=], such as its construction, whether part or all of it runs in a secure
    operating environment, and so on.

It is expected that most [=authenticators=] will support a small number of [=attestation types=] and [=attestation statement
formats=], while [=[RPS]=] will decide what [=attestation types=] are acceptable to them by policy. [=[RPS]=] will also need to
understand the characteristics of the [=authenticators=] that they trust, based on information they have about these
[=authenticators=]. For example, the FIDO Metadata Service [[FIDOMetadataService]] provides one way to access such information.


### Attested Credential Data ### {#sctn-attested-credential-data}

<dfn>Attested credential data</dfn> is a variable-length byte array added to the [=authenticator data=] when generating an [=attestation
object=] for a given credential. Its format is shown in <a href="#table-attestedCredentialData">Table <span class="table-ref-following"/></a>.

<figure id="table-attestedCredentialData" class="table">
    <table class="complex data longlastcol">
        <tr>
            <th>Name</th>
            <th>Length (in bytes)</th>
            <th>Description</th>
        </tr>
        <tr>
            <td><dfn>aaguid</dfn></td>
            <td>16</td>
            <td>The AAGUID of the authenticator.</td>
        </tr>
        <tr>
            <td><dfn>credentialIdLength</dfn></td>
            <td>2</td>
            <td>Byte length <strong>L</strong> of Credential ID, 16-bit unsigned big-endian integer.</td>
        </tr>
        <tr>
            <td><dfn>credentialId</dfn></td>
            <td>L</td>
            <td>[=Credential ID=]</td>
        </tr>
        <tr>
            <td><dfn>credentialPublicKey</dfn></td>
            <td>variable</td>
            <td>
                The [=credential public key=] encoded in COSE_Key format,
                as defined in [=Section 7=] of [[!RFC8152]], using the [=CTAP2 canonical CBOR encoding form=].
                The COSE_Key-encoded [=credential public key=] MUST contain the "alg" parameter and MUST NOT
                contain any other OPTIONAL parameters. The "alg" parameter MUST contain a {{COSEAlgorithmIdentifier}} value.
                The encoded [=credential public key=] MUST also contain any additional REQUIRED parameters stipulated by the
                relevant key type specification, i.e., REQUIRED for the key type "kty" and algorithm "alg" (see Section 8 of
                [[!RFC8152]]).
            </td>
        </tr>
    </table>
    <figcaption>
        [=Attested credential data=] layout. The names in the Name column are only for reference within this document, and are not
        present in the actual representation of the [=attested credential data=].
    </figcaption>
</figure>

#### Examples of `credentialPublicKey` Values Encoded in COSE_Key Format #### {#sctn-encoded-credPubKey-examples}

This section provides examples of COSE_Key-encoded Elliptic Curve and RSA public keys for the ES256, PS256, and RS256
signature algorithms. These examples adhere to the rules defined above for the [=credentialPublicKey=] value, and are presented in CDDL [[!RFC8610]] for clarity.

[[!RFC8152]] [=Section 7=] defines the general framework for all COSE_Key-encoded keys.
Specific key types for specific algorithms are defined in other sections of [[!RFC8152]] as well as in other specifications,
as noted below.

Below is an example of a COSE_Key-encoded Elliptic Curve public key in EC2 format (see [[!RFC8152]]
[=Section 13.1=]), on the P-256 curve, to be used with the ES256 signature
algorithm (ECDSA w/ SHA-256, see [[!RFC8152]] [=Section 8.1=]:

<pre class="example" highlight="json">
  {
    1:   2,  ; kty: EC2 key type
    3:  -7,  ; alg: ES256 signature algorithm
   -1:   1,  ; crv: P-256 curve
   -2:   x,  ; x-coordinate as byte string 32 bytes in length
             ; e.g., in hex: 65eda5a12577c2bae829437fe338701a10aaa375e1bb5b5de108de439c08551d
   -3:   y   ; y-coordinate as byte string 32 bytes in length
             ; e.g., in hex: 1e52ed75701163f7f9e40ddf9f341b3dc9ba860af7e0ca7ca7e9eecd0084d19c
  }
</pre>

Below is the above Elliptic Curve public key encoded in the [=CTAP2 canonical CBOR encoding form=], whitespace and line breaks
are included here for clarity and to match the CDDL [[!RFC8610]] presentation above:

<pre class="example" highlight="json">
  A5
     01  02

     03  26

     20  01

     21  58 20   65eda5a12577c2bae829437fe338701a10aaa375e1bb5b5de108de439c08551d

     22  58 20   1e52ed75701163f7f9e40ddf9f341b3dc9ba860af7e0ca7ca7e9eecd0084d19c
</pre>


Below is an example of a COSE_Key-encoded 2048-bit RSA public key (see [[RFC8230]] [=Section 4=],
to be used with the PS256 signature algorithm
(RSASSA-PSS with SHA-256, see [[RFC8230]] [=Section 2=]:

<pre class="example" highlight="json">
  {
    1:   3,  ; kty: RSA key type
    3: -37,  ; alg: PS256
   -1:   n,  ; n:   RSA modulus n byte string 256 bytes in length
             ;      e.g., in hex (middle bytes elided for brevity): DB5F651550...6DC6548ACC3
   -2:   e   ; e:   RSA public exponent e byte string 3 bytes in length
             ;      e.g., in hex: 010001
  }
</pre>

Below is an example of the same COSE_Key-encoded RSA public key as above,
to be used with the RS256 signature algorithm (RSASSA-PKCS1-v1_5 with SHA-256, see [[#sctn-cose-alg-reg]]):

<pre class="example" highlight="json">
  {
    1:   3,  ; kty: RSA key type
    3:-257,  ; alg: RS256
   -1:   n,  ; n:   RSA modulus n byte string 256 bytes in length
             ;      e.g., in hex (middle bytes elided for brevity): DB5F651550...6DC6548ACC3
   -2:   e   ; e:   RSA public exponent e byte string 3 bytes in length
             ;      e.g., in hex: 010001
  }
</pre>


### Attestation Statement Formats ### {#sctn-attestation-formats}

As described above, an [=attestation statement format=] is a data format which represents a cryptographic signature by an
[=authenticator=] over a set of contextual bindings. Each [=attestation statement format=] MUST be defined using the following
template:

- <strong>[=Attestation statement format identifier=]:</strong>

- <strong>Supported [=attestation types=]:</strong>

- <strong>Syntax:</strong>
    The syntax of an [=attestation statement=] produced in this format, defined using CDDL [[!RFC8610]] for the extension point
    `$attStmtFormat` defined in [[#sctn-generating-an-attestation-object]].

- <dfn>Signing procedure</dfn>:
    The [=signing procedure=] for computing an [=attestation statement=] in this [=attestation statement format|format=] given
    the [=public key credential=] to be attested, the [=authenticator data=] structure containing the <dfn>authenticator data
    for the attestation</dfn>, and the [=hash of the serialized client data=].

- <dfn>Verification procedure</dfn>:
    The procedure for verifying an [=attestation statement=], which takes the following <dfn>verification procedure inputs</dfn>:
    - |attStmt|: The [=attestation statement=] structure
    - |authenticatorData|: The  <dfn>[=authenticator data=] claimed to have been used for the attestation</dfn>
    - |clientDataHash|: The [=hash of the serialized client data=]

    The procedure returns either:
    - An error indicating that the attestation is invalid, or
    - An implementation-specific value representing the [=attestation type=], and the [=attestation trust path|trust path=]. This <dfn>attestation trust path</dfn> is either
        empty (in case of [=self attestation=]), an identifier of an [=ECDAA-Issuer public key=] (in the case of [=ECDAA=]), or a
        set of X.509 certificates.

The initial list of specified [=attestation statement formats=] is in [[#sctn-defined-attestation-formats]].


<!-- Editors Note: differentiating section IDs from non-section IDs is useful because at times we need to seperately reference
     different things having the same nominal name, eg attestation-types-the-section, and attestation-types-the-definition -->
### Attestation Types ### {#sctn-attestation-types}

WebAuthn supports several [=attestation types=], defining the semantics of [=attestation statements=] and their underlying trust
models:

Note: This specification does not define any data structures explicitly expressing the [=attestation types=] employed by
[=authenticators=]. [=[RPS]=] engaging in [=attestation statement=] [=verification procedure|verification=] &mdash; i.e., when
calling {{CredentialsContainer/create()|navigator.credentials.create()}} they select an [=attestation conveyance=] other than
{{AttestationConveyancePreference/none}} and verify the received [=attestation statement=] &mdash; will determine the employed
[=attestation type=] as a part of [=verification procedure|verification=]. See the "Verification procedure" subsections of
[[#sctn-defined-attestation-formats]]. See also [[#sctn-attestation-privacy]].

: <dfn>Basic Attestation</dfn> (<dfn>Basic</dfn>)
:: In the case of basic attestation [[UAFProtocol]], the authenticator's [=attestation key pair=] is specific to an
    authenticator model.  Thus, authenticators of the same model often share the same [=attestation key pair=]. See
    [[#sctn-attestation-privacy]] for further information.

    [=Basic attestation=] is sometimes also called <dfn>batch attestation</dfn>.

: <dfn>Self Attestation</dfn> (<dfn>Self</dfn>)
:: In the case of [=self attestation=], also known as surrogate basic attestation [[UAFProtocol]], the Authenticator does not have
    any specific [=attestation key pair=]. Instead it uses the [=credential private key=] to create the [=attestation signature=].
    Authenticators without meaningful protection measures for an [=attestation private key=] typically use this attestation type.

: <dfn>Attestation CA</dfn> (<dfn>AttCA</dfn>)
:: In this case, an [=authenticator=] is based on a Trusted Platform Module (TPM) and holds an authenticator-specific
    "endorsement key" (EK). This key is used to securely communicate with a trusted third party, the [=Attestation CA=]
    [[!TCG-CMCProfile-AIKCertEnroll]] (formerly known as a "Privacy CA"). The [=authenticator=] can generate multiple
    attestation identity key pairs (AIK) and requests an [=Attestation CA=] to issue an AIK certificate
    for each. Using this approach, such an [=authenticator=] can limit the exposure of the EK (which is a global correlation
    handle) to Attestation CA(s). AIKs can be requested for each [=authenticator=]-generated [=public key credential=]
    individually, and conveyed to [=[RPS]=] as [=attestation certificates=].

    Note: This concept typically leads to multiple attestation certificates. The attestation certificate requested most recently
        is called "active".

    Note: [=Attestation statements=] conveying [=attestations=] of [=attestation type|type=] [=AttCA=] use the same data structure
    as [=attestation statements=] conveying [=attestations=] of [=attestation type|type=] [=Basic=], so the two attestation types
    are, in general, distinguishable only with externally provided knowledge regarding the contents of the [=attestation
    certificates=] conveyed in the [=attestation statement=].

: <dfn>Elliptic Curve based Direct Anonymous Attestation</dfn> (<dfn>ECDAA</dfn>)
:: In this case, the Authenticator receives direct anonymous attestation (DAA) credentials from a single DAA-Issuer.
    These DAA credentials are used along with blinding to sign the [=attested credential data=]. The concept of blinding avoids
    the DAA credentials being misused as global correlation handle. WebAuthn supports DAA using elliptic curve cryptography and
    bilinear pairings, called [=ECDAA=] (see [[FIDOEcdaaAlgorithm]]) in this specification. Consequently we denote the DAA-Issuer
    as ECDAA-Issuer (see [[FIDOEcdaaAlgorithm]]).

: No attestation statement (<dfn>None</dfn>)
:: In this case, no attestation information is available. See also [[#sctn-none-attestation]].

### Generating an Attestation Object ### {#sctn-generating-an-attestation-object}

To generate an [=attestation object=] (see: [Figure 6](#fig-attStructs)) given:

: |attestationFormat|
:: An [=attestation statement format=].
: |authData|
:: A byte array containing [=authenticator data=].
: |hash|
:: The [=hash of the serialized client data=].

the [=authenticator=] MUST:

1. Let <var ignore>attStmt</var> be the result of running |attestationFormat|'s [=signing procedure=] given |authData| and
    |hash|.
1. Let <var ignore>fmt</var> be |attestationFormat|'s [=attestation statement format identifier=]
1. Return the [=attestation object=] as a CBOR map with the following syntax, filled in with variables initialized by this
    algorithm:

    ```
    attObj = {
                authData: bytes,
                $$attStmtType
             }

    attStmtTemplate = (
                          fmt: text,
                          attStmt: { * tstr => any } ; Map is filled in by each concrete attStmtType
                      )

    ; Every attestation statement format must have the above fields
    attStmtTemplate .within $$attStmtType
    ```

### Signature Formats for Packed Attestation, FIDO U2F Attestation, and Assertion Signatures ### {#sctn-signature-attestation-types}
    - For COSEAlgorithmIdentifier -7 (ES256),  and other ECDSA-based algorithms,
        a signature value is encoded as an ASN.1 DER Ecdsa-Sig-Value, as defined in [[RFC3279]] section 2.2.3.

        ```
        Example:
        30 44                                ; SEQUENCE (68 Bytes)
            02 20                            ; INTEGER (32 Bytes)
            |  3d 46 28 7b 8c 6e 8c 8c  26 1c 1b 88 f2 73 b0 9a
            |  32 a6 cf 28 09 fd 6e 30  d5 a7 9f 26 37 00 8f 54
            02 20                            ; INTEGER (32 Bytes)
            |  4e 72 23 6e a3 90 a9 a1  7b cf 5f 7a 09 d6 3a b2
            |  17 6c 92 bb 8e 36 c0 41  98 a2 7b 90 9b 6e 8f 13
        ```

        Note: As CTAP1/U2F [=authenticators=] are already producing signatures values in this format, CTAP2
        [=authenticators=] will also produce signatures values in the same format, for consistency reasons.
        It is recommended that any new attestation formats defined not use ASN.1 encodings,
        but instead represent signatures as equivalent fixed-length byte arrays without internal structure,
        using the same representations as used by COSE signatures as defined in [[!RFC8152]] and [[!RFC8230]].

    - For COSEAlgorithmIdentifier -257 (RS256), `sig` contains the signature generated using the
        RSASSA-PKCS1-v1_5 signature scheme defined in section 8.2.1 in [[RFC8017]] with SHA-256 as the hash function.
        The signature is not ASN.1 wrapped.

    - For COSEAlgorithmIdentifier -37 (PS256), `sig` contains the signature generated using the
        RSASSA-PSS signature scheme defined in section 8.1.1 in [[RFC8017]] with SHA-256 as the hash function.
        The signature is not ASN.1 wrapped.

# [=[WRP]=] Operations # {#sctn-rp-operations}

A [=registration ceremony|registration=] or [=authentication ceremony=] begins with the [=[WRP]=] creating a {{PublicKeyCredentialCreationOptions}}
or {{PublicKeyCredentialRequestOptions}} object, respectively, which encodes the parameters for the [=ceremony=]. The [=[RP]=]
SHOULD take care to not leak sensitive information during this stage; see [[#sctn-username-enumeration]] for details.

Upon successful execution of {{CredentialsContainer/create()}} or {{CredentialsContainer/get()}}, the [=[RP]=]'s script receives
a {{PublicKeyCredential}} containing an {{AuthenticatorAttestationResponse}} or {{AuthenticatorAssertionResponse}} structure,
respectively, from the client. It must then deliver the contents of this structure to the [=[RP]=] server, using methods outside
the scope of this specification. This section describes the operations that the [=[RP]=] must perform upon receipt of these
structures.


## Registering a New Credential ## {#sctn-registering-a-new-credential}

In order to perform a [=registration ceremony=], the [=[RP]=] MUST proceed as follows:

1. Let |options| be a new {{PublicKeyCredentialCreationOptions}} structure configured to the [=[RP]=]'s needs for the ceremony.

1. Call {{CredentialsContainer/create()|navigator.credentials.create()}} and pass |options|
    as the <code>{{CredentialCreationOptions/publicKey}}</code> option.
    Let |credential| be the result of the successfully resolved promise.
    If the promise is rejected, abort the ceremony with a user-visible error.

1. Let |response| be <code>|credential|.{{PublicKeyCredential/response}}</code>.
    If |response| is not an instance of {{AuthenticatorAttestationResponse}}, abort the ceremony with a user-visible error.

1. Let |clientExtensionResults| be the result of calling
    <code>|credential|.{{PublicKeyCredential/getClientExtensionResults()}}</code>.

1. Let |JSONtext| be the result of
    running [=UTF-8 decode=] on the value of <code>|response|.{{AuthenticatorResponse/clientDataJSON}}</code>.

    Note: Using any implementation of [=UTF-8 decode=] is acceptable as long as it yields the same result as that yielded by
    the [=UTF-8 decode=] algorithm. In particular, any leading byte order mark (BOM) MUST be stripped.

1. Let |C|, the [=client data=] claimed as collected during the credential creation, be the result of running an
    implementation-specific JSON parser on |JSONtext|.

    Note: |C| may be any implementation-specific data structure representation, as long as |C|'s components are referenceable, as
    required by this algorithm.

1. Verify that the value of <code>|C|.{{CollectedClientData/type}}</code> is `webauthn.create`.

1. Verify that the value of <code>|C|.{{CollectedClientData/challenge}}</code> equals
    the base64url encoding of <code>|options|.{{PublicKeyCredentialCreationOptions/challenge}}</code>.

1. Verify that the value of <code>|C|.{{CollectedClientData/origin}}</code> matches the [=[RP]=]'s [=origin=].

1. Verify that the value of <code>|C|.{{CollectedClientData/tokenBinding}}.{{TokenBinding/status}}</code> matches the state of [=Token Binding=] for the TLS connection over which the [=assertion=] was obtained. If [=Token Binding=] was used on that TLS connection, also verify that <code>|C|.{{CollectedClientData/tokenBinding}}.{{TokenBinding/id}}</code> matches the [=base64url encoding=] of the [=Token Binding ID=] for the connection.

1. Let |hash| be the result of computing a hash over <code>|response|.{{AuthenticatorResponse/clientDataJSON}}</code> using SHA-256.

1. Perform CBOR decoding on the {{AuthenticatorAttestationResponse/attestationObject}} field of the
    {{AuthenticatorAttestationResponse}} structure to obtain the attestation statement format |fmt|, the [=authenticator data=]
    |authData|, and the attestation statement |attStmt|.

1. Verify that the <code>[=rpIdHash=]</code> in |authData| is the SHA-256 hash of the [=RP ID=] expected by the [=[RP]=].

1. Verify that the [=User Present=] bit of the <code>[=flags=]</code> in |authData| is set.

1. If [=user verification=] is required for this registration, verify that the [=User Verified=] bit of the <code>[=flags=]</code>
    in |authData| is set.

1. Verify that the "alg" parameter in the [=credentialPublicKey|credential public key=] in |authData|
    matches the {{PublicKeyCredentialParameters/alg}} attribute of one of the [=list/items=] in
    <code>|options|.{{PublicKeyCredentialCreationOptions/pubKeyCredParams}}</code>.

1. Verify that the values of the [=client extension outputs=] in |clientExtensionResults| and the [=authenticator extension
    outputs=] in the <code>[=authdataextensions|extensions=]</code> in |authData| are as expected, considering the [=client
    extension input=] values that were given in <code>|options|.{{PublicKeyCredentialCreationOptions/extensions}}</code>
    and any specific policy of the [=[RP]=] regarding unsolicited extensions, i.e., those that were not specified as part of
    <code>|options|.{{PublicKeyCredentialCreationOptions/extensions}}</code>.
    In the general case, the meaning of "are as expected" is specific to the [=[RP]=] and which extensions are in use.

    Note:  [=Client platforms=] MAY enact local policy that sets additional [=authenticator extensions=] or
    [=client extensions=] and thus cause values to appear in the [=authenticator extension outputs=] or
    [=client extension outputs=] that were not originally specified as part of
    <code>|options|.{{PublicKeyCredentialCreationOptions/extensions}}</code>. [=[RPS]=] MUST be prepared to handle such
    situations, whether it be to ignore the unsolicited extensions or reject the attestation. The [=[RP]=] can make this
    decision based on local policy and the extensions in use.

    Note: Since all extensions are OPTIONAL for both the [=client=] and the [=authenticator=], the [=[RP]=] MUST also be
    prepared to handle cases where none or not all of the requested extensions were acted upon.

1. Determine the attestation statement format by performing a USASCII case-sensitive match on |fmt| against the set of
    supported WebAuthn Attestation Statement Format Identifier values.
    An up-to-date list of registered WebAuthn Attestation Statement Format Identifier values
    is maintained in the IANA registry of the same name [[!WebAuthn-Registries]].

1. Verify that |attStmt| is a correct [=attestation statement=], conveying a valid [=attestation signature=], by using the
    [=attestation statement format=] |fmt|'s [=verification procedure=] given |attStmt|, |authData| and |hash|.

    Note: Each [=attestation statement format=] specifies its own [=verification procedure=]. See [[#sctn-defined-attestation-formats]] for
    the initially-defined formats, and [[!WebAuthn-Registries]] for the up-to-date list.

1. If validation is successful, obtain a list of acceptable trust anchors (attestation root certificates or [=ECDAA-Issuer
    public key=]s) for that attestation type and attestation statement format |fmt|, from a trusted source or from policy. For
    example, the FIDO Metadata Service [[FIDOMetadataService]] provides one way to obtain such information, using the
    <code>[=aaguid=]</code> in the <code>[=attestedCredentialData=]</code> in |authData|.

1. Assess the attestation trustworthiness using the outputs of the [=verification procedure=] in step 19, as follows:
        - If [=None|no attestation=] was provided, verify that [=None=] attestation is acceptable under [=[RP]=] policy.
        - If [=self attestation=] was used, verify that [=self attestation=] is acceptable under [=[RP]=] policy.
        - If [=ECDAA=] was used, verify that the [=identifier of the ECDAA-Issuer public key=],
             returned as the [=attestation trust path=] from the [=verification procedure=],
             is included in the set of acceptable trust anchors obtained in step 20.
        - Otherwise, use the X.509 certificates returned as the [=attestation trust path=] from the [=verification procedure=]
            to verify that the attestation public key correctly chains up to an acceptable root certificate.

1. Check that the <code>[=credentialId=]</code> is not yet registered to any other user. If registration
    is requested for a credential that is already registered to a different user, the [=[RP]=] SHOULD
    fail this [=registration ceremony=], or it MAY decide to accept the registration, e.g. while deleting the older registration.

1. If the attestation statement |attStmt| verified successfully and is found to be trustworthy, then register the new
    credential with the account that was denoted in <code>|options|.{{PublicKeyCredentialCreationOptions/user}}</code>:

    - Associate the user's account with the <code>[=credentialId=]</code> and <code>[=credentialPublicKey=]</code>
        in <code>|authData|.[=attestedCredentialData=]</code>, as appropriate for the [=[RP]=]'s system.
    - Associate the <code>[=credentialId=]</code> with a new stored [=signature counter=] value
        initialized to the value of <code>|authData|.[=signCount=]</code>.

    It is RECOMMENDED to also:

    - Associate the <code>[=credentialId=]</code> with the transport hints
        returned by calling <code>|credential|.{{AuthenticatorAttestationResponse/getTransports()}}</code>.
        It is RECOMMENDED to use these to populate the {{PublicKeyCredentialDescriptor/transports}}
        of the {{PublicKeyCredentialRequestOptions/allowCredentials}} option in future {{CredentialsContainer/get()}} calls
        to help the [=client=] know how to find a suitable [=authenticator=].

1. If the attestation statement |attStmt| successfully verified but is not trustworthy per step 21 above, the [=[RP]=] SHOULD fail
    the [=registration ceremony=].

    NOTE: However, if permitted by policy, the [=[RP]=] MAY register the [=credential ID=] and credential public key but treat the
        credential as one with [=self attestation=] (see [[#sctn-attestation-types]]). If doing so, the [=[RP]=] is asserting there
        is no cryptographic proof that the [=public key credential=] has been generated by a particular [=authenticator=] model.
        See [[FIDOSecRef]] and [[UAFProtocol]] for a more detailed discussion.

Verification of [=attestation objects=] requires that the [=[RP]=] has a trusted method of determining acceptable trust anchors
in step 20 above. Also, if certificates are being used, the [=[RP]=] MUST have access to certificate status information for the
intermediate CA certificates. The [=[RP]=] MUST also be able to build the attestation certificate chain if the client did not
provide this chain in the attestation information.


## Verifying an Authentication Assertion ## {#sctn-verifying-assertion}

In order to perform an [=authentication ceremony=], the [=[RP]=] MUST proceed as follows:

1. Let |options| be a new {{PublicKeyCredentialRequestOptions}} structure configured to the [=[RP]=]'s needs for the ceremony.

1. Call {{CredentialsContainer/get()|navigator.credentials.get()}} and pass |options|
    as the <code>{{CredentialRequestOptions/publicKey}}</code> option.
    Let |credential| be the result of the successfully resolved promise.
    If the promise is rejected, abort the ceremony with a user-visible error.

1. Let |response| be <code>|credential|.{{PublicKeyCredential/response}}</code>.
    If |response| is not an instance of {{AuthenticatorAssertionResponse}}, abort the ceremony with a user-visible error.

1. Let |clientExtensionResults| be the result of calling <code>|credential|.{{PublicKeyCredential/getClientExtensionResults()}}</code>.

1. If <code>|options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}</code> [=list/is not empty=],
    verify that <code>|credential|.{{Credential/id}}</code> identifies one of the [=public key credentials=]
    listed in <code>|options|.{{PublicKeyCredentialRequestOptions/allowCredentials}}</code>.

1. Identify the user being authenticated and verify that this user is the owner of the [=public key credential source=]
    |credentialSource| identified by <code>|credential|.{{Credential/id}}</code>:

    <dl class="switch">
        :  If the user was identified before the [=authentication ceremony=] was initiated, e.g., via a username or cookie,
        :: verify that the identified user is the owner of |credentialSource|. If
            <code>|response|.{{AuthenticatorAssertionResponse/userHandle}}</code> is present,
            let |userHandle| be its value. Verify that |userHandle| also maps to the same user.

        :  If the user was not identified before the [=authentication ceremony=] was initiated,
        :: verify that <code>|response|.{{AuthenticatorAssertionResponse/userHandle}}</code> is
            present, and that the user identified by this value is the owner of |credentialSource|.
    </dl>

1. Using <code>|credential|.{{Credential/id}}</code> (or <code>|credential|.{{PublicKeyCredential/rawId}}</code>, if
    [=base64url encoding=] is inappropriate for your use case), look up the corresponding [=credential public key=]
    and let |credentialPublicKey| be that [=credential public key=].

1. Let |cData|, |authData| and |sig| denote the value of |response|'s
    {{AuthenticatorResponse/clientDataJSON}}, {{AuthenticatorAssertionResponse/authenticatorData}}, and
    {{AuthenticatorAssertionResponse/signature}} respectively.

1. Let |JSONtext| be the result of running [=UTF-8 decode=] on the value of |cData|.

    Note: Using any implementation of [=UTF-8 decode=] is acceptable as long as it yields the same result as that yielded by
    the [=UTF-8 decode=] algorithm. In particular, any leading byte order mark (BOM) MUST be stripped.

1. Let |C|, the [=client data=] claimed as used for the signature, be the result of running an implementation-specific
    JSON parser on |JSONtext|.

    Note: |C| may be any implementation-specific data structure representation, as long as |C|'s components are referenceable, as
    required by this algorithm.

1. Verify that the value of <code>|C|.{{CollectedClientData/type}}</code> is the string `webauthn.get`.

1. Verify that the value of <code>|C|.{{CollectedClientData/challenge}}</code> equals
    the base64url encoding of <code>|options|.{{PublicKeyCredentialRequestOptions/challenge}}</code>.

1. Verify that the value of <code>|C|.{{CollectedClientData/origin}}</code> matches the [=[RP]=]'s [=origin=].

1. Verify that the value of <code>|C|.{{CollectedClientData/tokenBinding}}.{{TokenBinding/status}}</code> matches the state of [=Token Binding=] for the TLS connection over which the attestation was obtained. If [=Token Binding=] was used on that TLS connection, also verify that <code>|C|.{{CollectedClientData/tokenBinding}}.{{TokenBinding/id}}</code> matches the [=base64url encoding=] of the [=Token Binding ID=] for the connection.

<!-- Note: this next step is actually a top-level step, but bikeshed wanted it indented this much in order to render it as
a numbered step. If outdented, it (today) is rendered as a bullet in the midst of a numbered list :-/
-->
    <li id='rp-op-verifying-assertion-step-rpid-hash'>
      Verify that the <code>[=rpIdHash=]</code> in |authData| is the SHA-256 hash of the [=RP ID=] expected by the [=[RP]=].

      Note: If using the [=appid=] extension, this step needs some special logic. See [[#sctn-appid-extension]] for details.
    </li>

1. Verify that the [=User Present=] bit of the <code>[=flags=]</code> in |authData| is set.

1. If [=user verification=] is required for this assertion, verify that the [=User Verified=] bit of the <code>[=flags=]</code> in
    |authData| is set.

1. Verify that the values of the [=client extension outputs=] in |clientExtensionResults| and the [=authenticator extension
    outputs=] in the <code>[=authdataextensions|extensions=]</code> in |authData| are as expected, considering the [=client
    extension input=] values that were given in <code>|options|.{{PublicKeyCredentialRequestOptions/extensions}}</code>
    and any specific policy of the [=[RP]=] regarding unsolicited extensions, i.e., those that were not specified as part of
    <code>|options|.{{PublicKeyCredentialRequestOptions/extensions}}</code>.
    In the general case, the meaning of "are as expected" is specific to the [=[RP]=] and which extensions are in use.

    Note:  [=Client platforms=] MAY enact local policy that sets additional [=authenticator extensions=] or
    [=client extensions=] and thus cause values to appear in the [=authenticator extension outputs=] or
    [=client extension outputs=] that were not originally specified as part of
    <code>|options|.{{PublicKeyCredentialRequestOptions/extensions}}</code>. [=[RPS]=] MUST be prepared to handle such
    situations, whether it be to ignore the unsolicited extensions or reject the assertion. The [=[RP]=] can make this
    decision based on local policy and the extensions in use.

    Note: Since all extensions are OPTIONAL for both the [=client=] and the [=authenticator=], the [=[RP]=] MUST also be
    prepared to handle cases where none or not all of the requested extensions were acted upon.

1. Let |hash| be the result of computing a hash over the |cData| using SHA-256.

1. Using |credentialPublicKey|, verify that |sig| is a valid signature over the binary concatenation of
    |authData| and |hash|.

    Note: This verification step is compatible with signatures generated by FIDO U2F authenticators. See
    [[#sctn-fido-u2f-sig-format-compat]].

1. Let |storedSignCount| be the stored [=signature counter=] value associated with <code>|credential|.{{Credential/id}}</code>.
    If |authData|.<code>[=signCount=]</code> is nonzero or |storedSignCount| is nonzero,
    then run the following sub-step:
      - If |authData|.<code>[=signCount=]</code> is
           <dl class="switch">
              <dt>greater than |storedSignCount|:</dt>
              <dd>Update |storedSignCount| to be the value of
                  |authData|.<code>[=signCount=]</code>.</dd>
              <dt>less than or equal to |storedSignCount|:</dt>
              <dd>This is a signal that
                  the authenticator may be cloned, i.e. at least
                  two copies of the [=credential private key=] may exist and are
                  being used in parallel. [=[RPS]=] should incorporate this information
                  into their risk scoring.  Whether the [=[RP]=] updates |storedSignCount|
                  in this case, or not, or fails the
                  [=authentication ceremony=] or not, is
                  [=[RP]=]-specific. </dd>
           </dl>

1. If all the above steps are successful, continue with the [=authentication ceremony=] as appropriate. Otherwise, fail the
    [=authentication ceremony=].


# Defined Attestation Statement Formats # {#sctn-defined-attestation-formats}

WebAuthn supports pluggable attestation statement formats. This section defines an initial set of such formats.

## Attestation Statement Format Identifiers ## {#sctn-attstn-fmt-ids}

Attestation statement formats are identified by a string, called an <dfn>attestation statement format identifier</dfn>, chosen by
the author of the [=attestation statement format=].

Attestation statement format identifiers SHOULD be registered per [[!WebAuthn-Registries]] "Registries for Web Authentication
(WebAuthn)". All registered attestation statement format identifiers are unique amongst themselves as a matter of course.

Unregistered attestation statement format identifiers SHOULD use lowercase reverse domain-name naming, using a domain name
registered by the developer, in order to assure uniqueness of the identifier. All attestation statement format identifiers MUST
be a maximum of 32 octets in length and MUST consist only of printable USASCII characters, excluding backslash and doublequote,
i.e., VCHAR as defined in [[!RFC5234]] but without %x22 and %x5c.

Note: This means attestation statement format identifiers based on domain names MUST incorporate only LDH Labels [[!RFC5890]].

Implementations MUST match WebAuthn attestation statement format identifiers in a case-sensitive fashion.

Attestation statement formats that may exist in multiple versions SHOULD include a version in their identifier. In effect,
different versions are thus treated as different formats, e.g., `packed2` as a new version of the [[#sctn-packed-attestation]].

The following sections present a set of currently-defined and registered attestation statement formats and their identifiers.
The up-to-date list of registered [=WebAuthn Extensions=] is maintained in the IANA "WebAuthn Attestation Statement Format
Identifier" registry established by [[!WebAuthn-Registries]].


## Packed Attestation Statement Format ## {#sctn-packed-attestation}

This is a WebAuthn optimized attestation statement format. It uses a very compact but still extensible encoding method. It is
implementable by [=authenticators=] with limited resources (e.g., secure elements).

: Attestation statement format identifier
:: packed

: Attestation types supported
:: [=Basic=], [=Self=], [=AttCA=], [=ECDAA=]

: Syntax
:: The syntax of a Packed Attestation statement is defined by the following CDDL:

    ```
    $$attStmtType //= (
                          fmt: "packed",
                          attStmt: packedStmtFormat
                      )

    packedStmtFormat = {
                           alg: COSEAlgorithmIdentifier,
                           sig: bytes,
                           x5c: [ attestnCert: bytes, * (caCert: bytes) ]
                       } //
                       {
                           alg: COSEAlgorithmIdentifier, (-260 for ED256 / -261 for ED512)
                           sig: bytes,
                           ecdaaKeyId: bytes
                       } //
                       {
                           alg: COSEAlgorithmIdentifier
                           sig: bytes,
                       }
    ```

    The semantics of the fields are as follows:

    : alg
    :: A {{COSEAlgorithmIdentifier}} containing the identifier of the algorithm used to generate the [=attestation signature=].

    : sig
    :: A byte string containing the [=attestation signature=].

    : x5c
    :: The elements of this array contain |attestnCert| and its certificate chain, each encoded in X.509 format. The attestation
        certificate |attestnCert| MUST be the first element in the array.

    : attestnCert
    :: The attestation certificate, encoded in X.509 format.

    : ecdaaKeyId
    :: The <dfn>identifier of the ECDAA-Issuer public key</dfn>.  This is the
        BigNumberToB encoding of the component "c" of the <dfn>ECDAA-Issuer public key</dfn>
        as defined section 3.3, step 3.5 in [[!FIDOEcdaaAlgorithm]].

: Signing procedure
:: The signing procedure for this attestation statement format is
    similar to [the procedure for generating assertion signatures](#fig-signature).
        1. Let |authenticatorData| denote the [=authenticator data for the attestation=],
            and let |clientDataHash| denote the [=hash of the serialized client data=].

        1. If [=Basic=] or [=AttCA=] [=attestation=] is in use, the authenticator produces the |sig| by concatenating |authenticatorData| and
            |clientDataHash|, and signing the result using an [=attestation private key=] selected through an authenticator-specific
            mechanism. It sets |x5c| to the certificate chain of the [=attestation public key=] and |alg| to the algorithm of the
            attestation private key.

        1. If [=ECDAA=] is in use, the authenticator produces |sig| by concatenating |authenticatorData| and |clientDataHash|, and
            signing the result using ECDAA-Sign (see section 3.5 of [[!FIDOEcdaaAlgorithm]]) after selecting an
            [=ECDAA-Issuer public key=] related to the ECDAA signature private key through an
            authenticator-specific mechanism (see [[!FIDOEcdaaAlgorithm]]). It sets |alg| to the algorithm of the selected
            [=ECDAA-Issuer public key=] and |ecdaaKeyId| to the [=identifier of the ECDAA-Issuer public key=] (see above).

        1. If [=self attestation=] is in use, the authenticator produces |sig| by concatenating |authenticatorData| and |clientDataHash|,
            and signing the result using the credential private key. It sets |alg| to the algorithm of the credential private key and
            omits the other fields.

: Verification procedure
:: Given the [=verification procedure inputs=] |attStmt|, |authenticatorData| and |clientDataHash|, the [=verification procedure=] is
    as follows:

        1. Verify that |attStmt| is valid CBOR conforming to the syntax defined above and perform CBOR decoding on it to extract
            the contained fields.

        1. If |x5c| is present, this indicates that the attestation type is not [=ECDAA=]. In this case:
            - Verify that |sig| is a valid signature over the concatenation of |authenticatorData| and |clientDataHash| using the
                attestation public key in |attestnCert| with the algorithm specified in |alg|.
            - Verify that |attestnCert| meets the requirements in [[#sctn-packed-attestation-cert-requirements]].
            - If |attestnCert| contains an extension with OID 1.3.6.1.4.1.45724.1.1.4 (`id-fido-gen-ce-aaguid`) verify that the
                value of this extension matches the <code>[=aaguid=]</code> in |authenticatorData|.
            - Optionally, inspect |x5c| and consult externally provided knowledge to determine whether |attStmt| conveys a
                [=Basic=] or [=AttCA=] attestation.
            - If successful, return implementation-specific values representing [=attestation type=] [=Basic=], [=AttCA=] or
                uncertainty, and [=attestation trust path=] |x5c|.

        1. If |ecdaaKeyId| is present, then the attestation type is [=ECDAA=]. In this case:
            - Verify that |sig| is a valid signature over the concatenation of |authenticatorData| and |clientDataHash| using
                ECDAA-Verify with [=ECDAA-Issuer public key=] identified by |ecdaaKeyId| (see [[!FIDOEcdaaAlgorithm]]).
            - If successful, return implementation-specific values representing [=attestation type=] [=ECDAA=] and [=attestation
                trust path=] |ecdaaKeyId|.

        1. If neither |x5c| nor |ecdaaKeyId| is present, [=self attestation=] is in use.
            - Validate that |alg| matches the algorithm of the <code>[=credentialPublicKey=]</code> in |authenticatorData|.
            - Verify that |sig| is a valid signature over the concatenation of |authenticatorData| and |clientDataHash| using the
                credential public key with |alg|.
            - If successful, return implementation-specific values representing [=attestation type=] [=Self=] and an empty
                [=attestation trust path=].


### Packed Attestation Statement Certificate Requirements ### {#sctn-packed-attestation-cert-requirements}

The attestation certificate MUST have the following fields/extensions:

- Version MUST be set to 3 (which is indicated by an ASN.1 INTEGER with value 2).
- Subject field MUST be set to:
    : Subject-C
    :: ISO 3166 code specifying the country where the Authenticator vendor is incorporated (PrintableString)
    : Subject-O
    :: Legal name of the Authenticator vendor (UTF8String)
    : Subject-OU
    :: Literal string “Authenticator Attestation” (UTF8String)
    : Subject-CN
    :: A UTF8String of the vendor's choosing

- If the related attestation root certificate is used for multiple authenticator models, the Extension OID
    1.3.6.1.4.1.45724.1.1.4 (`id-fido-gen-ce-aaguid`) MUST be present, containing the AAGUID as a 16-byte OCTET STRING.
    The extension MUST NOT be marked as critical.

    Note that an X.509 Extension encodes the DER-encoding of the value in an OCTET STRING.
    Thus, the AAGUID MUST be wrapped in <i>two</i> OCTET STRINGS to be valid. Here is a sample, encoded Extension structure:

    <pre>
  30 21                                     -- SEQUENCE
    06 0b 2b 06 01 04 01 82 e5 1c 01 01 04  -- 1.3.6.1.4.1.45724.1.1.4
    04 12                                   -- OCTET STRING
      04 10                                 -- OCTET STRING
        cd 8c 39 5c 26 ed ee de             -- AAGUID
        65 3b 00 79 7d 03 ca 3c
    </pre>

- The Basic Constraints extension MUST have the CA component set to [FALSE].

- An Authority Information Access (AIA) extension with entry `id-ad-ocsp` and a CRL Distribution Point extension [[RFC5280]]
    are both OPTIONAL as the status of many attestation certificates is available through authenticator metadata services.
    See, for example, the FIDO Metadata Service [[FIDOMetadataService]].


## TPM Attestation Statement Format ## {#sctn-tpm-attestation}

This attestation statement format is generally used by authenticators that use a Trusted Platform Module as their cryptographic
engine.

: Attestation statement format identifier
:: tpm

: Attestation types supported
:: [=AttCA=], [=ECDAA=]

: Syntax
:: The syntax of a TPM Attestation statement is as follows:

    ```
    $$attStmtType // = (
                           fmt: "tpm",
                           attStmt: tpmStmtFormat
                       )

    tpmStmtFormat = {
                        ver: "2.0",
                        (
                            alg: COSEAlgorithmIdentifier,
                            x5c: [ aikCert: bytes, * (caCert: bytes) ]
                        ) //
                        (
                            alg:  COSEAlgorithmIdentifier, (-260 for ED256 / -261 for ED512)
                            ecdaaKeyId: bytes
                        ),
                        sig: bytes,
                        certInfo: bytes,
                        pubArea: bytes
                    }
    ```

    The semantics of the above fields are as follows:

    : ver
    :: The version of the TPM specification to which the signature conforms.

    : alg
    :: A {{COSEAlgorithmIdentifier}} containing the identifier of the algorithm used to generate the [=attestation signature=].

    : x5c
    :: |aikCert| followed by its certificate chain, in X.509 encoding.

    : aikCert
    :: The AIK certificate used for the attestation, in X.509 encoding.

    : ecdaaKeyId
    :: The [=identifier of the ECDAA-Issuer public key=]. This is the
        BigNumberToB encoding of the component "c" as defined section 3.3,
        step 3.5 in [[!FIDOEcdaaAlgorithm]].

    : sig
    :: The [=attestation signature=], in the form of a TPMT_SIGNATURE structure as specified in [[!TPMv2-Part2]] section 11.3.4.

    : certInfo
    :: The TPMS_ATTEST structure over which the above signature was computed, as specified in [[!TPMv2-Part2]] section 10.12.8.

    : pubArea
    :: The TPMT_PUBLIC structure (see [[!TPMv2-Part2]] section 12.2.4) used by the TPM to represent the credential public key.

: Signing procedure
:: Let |authenticatorData| denote the [=authenticator data for the attestation=], and let |clientDataHash| denote the
    [=hash of the serialized client data=].

    Concatenate |authenticatorData| and |clientDataHash| to form |attToBeSigned|.

    Generate a signature using the procedure specified in [[!TPMv2-Part3]] Section 18.2, using the attestation private key and
    setting the `extraData` parameter to the digest of |attToBeSigned| using the hash algorithm corresponding to the "alg" signature algorithm.
    (For the "RS256" algorithm, this would be a SHA-256 digest.)

    Set the |pubArea| field to the public area of the credential public key, the |certInfo| field to the output parameter of the
    same name, and the |sig| field to the signature obtained from the above procedure.

: Verification procedure
:: Given the [=verification procedure inputs=] |attStmt|, |authenticatorData| and |clientDataHash|, the [=verification procedure=] is
    as follows:

    Verify that |attStmt| is valid CBOR conforming to the syntax defined above and perform CBOR decoding on it to extract the
    contained fields.

    Verify that the public key specified by the `parameters` and `unique` fields of |pubArea| is identical to the
    <code>[=credentialPublicKey=]</code> in the <code>[=attestedCredentialData=]</code> in |authenticatorData|.

    Concatenate |authenticatorData| and |clientDataHash| to form |attToBeSigned|.

    Validate that |certInfo| is valid:
    - Verify that `magic` is set to `TPM_GENERATED_VALUE`.
    - Verify that `type` is set to `TPM_ST_ATTEST_CERTIFY`.
    - Verify that `extraData` is set to the hash of |attToBeSigned| using the hash algorithm employed in "alg".
    - Verify that `attested` contains a `TPMS_CERTIFY_INFO` structure as specified in [[!TPMv2-Part2]] section 10.12.3,
        whose `name` field contains a valid Name for |pubArea|,
        as computed using the algorithm in the `nameAlg` field of |pubArea| using the procedure specified in [[!TPMv2-Part1]]
        section 16.
    - Note that the remaining fields in the "Standard Attestation Structure" [[!TPMv2-Part1]]
        section 31.2, i.e., `qualifiedSigner`, `clockInfo` and `firmwareVersion` are ignored.
        These fields MAY be used as an input to risk engines.

    If |x5c| is present, this indicates that the attestation type is not [=ECDAA=]. In this case:
    - Verify the |sig| is a valid signature over |certInfo| using the attestation public key in |aikCert| with the
        algorithm specified in |alg|.
    - Verify that |aikCert| meets the requirements in [[#sctn-tpm-cert-requirements]].
    - If |aikCert| contains an extension with OID `1 3 6 1 4 1 45724 1 1 4` (id-fido-gen-ce-aaguid) verify that the value of this
        extension matches the <code>[=aaguid=]</code> in |authenticatorData|.
    - If successful, return implementation-specific values representing [=attestation type=] [=AttCA=] and [=attestation trust
        path=] |x5c|.

    If |ecdaaKeyId| is present, then the attestation type is [=ECDAA=].
    - Perform ECDAA-Verify on |sig| to verify that it is a valid signature over |certInfo| (see [[!FIDOEcdaaAlgorithm]]).
    - If successful, return implementation-specific values representing [=attestation type=] [=ECDAA=] and [=attestation trust
        path=] |ecdaaKeyId|.


### TPM Attestation Statement Certificate Requirements ### {#sctn-tpm-cert-requirements}

TPM [=attestation certificate=] MUST have the following fields/extensions:

- Version MUST be set to 3.

- Subject field MUST be set to empty.

- The Subject Alternative Name extension MUST be set as defined in [[!TPMv2-EK-Profile]] section 3.2.9.

- The Extended Key Usage extension MUST contain the
    "joint-iso-itu-t(2) internationalorganizations(23) 133 tcg-kp(8) tcg-kp-AIKCertificate(3)" OID.

- The Basic Constraints extension MUST have the CA component set to [FALSE].

- An Authority Information Access (AIA) extension with entry `id-ad-ocsp` and a CRL Distribution Point extension [[RFC5280]] are
    both OPTIONAL as the status of many attestation certificates is available through metadata services.
    See, for example, the FIDO Metadata Service [[FIDOMetadataService]].


## Android Key Attestation Statement Format ## {#sctn-android-key-attestation}

When the [=authenticator=] in question is a [=platform authenticator=] on the Android "N" or later platform, the
attestation statement is based on the [Android key
attestation](https://source.android.com/security/keystore/attestation). In these cases, the attestation statement
is produced by a component running in a secure operating environment, but the [=authenticator data for the attestation=] is
produced outside this environment. The [=[WRP]=] is expected to check that the [=authenticator data claimed to have been used for
the attestation=] is consistent with the fields of the attestation certificate's extension data.


: Attestation statement format identifier
:: android-key

: Attestation types supported
:: [=Basic=]

: Syntax
:: An Android key attestation statement consists simply of the Android attestation statement, which is a series of
    DER encoded X.509 certificates. See
    [the Android developer documentation](https://developer.android.com/training/articles/security-key-attestation.html). Its
    syntax is defined as follows:

    ```
    $$attStmtType //= (
                          fmt: "android-key",
                          attStmt: androidStmtFormat
                      )

    androidStmtFormat = {
                          alg: COSEAlgorithmIdentifier,
                          sig: bytes,
                          x5c: [ credCert: bytes, * (caCert: bytes) ]
                        }

    ```

: Signing procedure
:: Let |authenticatorData| denote the [=authenticator data for the attestation=], and let |clientDataHash| denote the
    [=hash of the serialized client data=].

    Request an Android Key Attestation by calling <code>keyStore.getCertificateChain(myKeyUUID)</code> providing |clientDataHash| as the
    challenge value (e.g., by using <a
    href="https://developer.android.com/reference/android/security/keystore/KeyGenParameterSpec.Builder.html#setAttestationChallenge(byte%5B%5D)">
    setAttestationChallenge</a>). Set |x5c| to the returned value.

    The authenticator produces |sig| by concatenating |authenticatorData| and |clientDataHash|,
    and signing the result using the credential private key. It sets |alg| to the algorithm of the signature format.


: Verification procedure
:: Given the [=verification procedure inputs=] |attStmt|, |authenticatorData| and |clientDataHash|, the [=verification procedure=] is
    as follows:
    - Verify that |attStmt| is valid CBOR conforming to the syntax defined above and perform CBOR decoding on it to extract the
        contained fields.
    - Verify that |sig| is a valid signature over the concatenation of |authenticatorData| and |clientDataHash| using the
        public key in the first certificate in |x5c| with the algorithm specified in |alg|.
    - Verify that the public key in the first certificate in |x5c| matches the
        <code>[=credentialPublicKey=]</code> in the <code>[=attestedCredentialData=]</code> in |authenticatorData|.
    - Verify that the `attestationChallenge` field in the [=attestation certificate=]
        [=android key attestation certificate extension data|extension data=] is identical to |clientDataHash|.
    - Verify the following using the appropriate authorization list from the attestation certificate
        [=android key attestation certificate extension data|extension data=]:
        - The `AuthorizationList.allApplications` field is <em>not</em> present on either authorization list
            (`softwareEnforced` nor `teeEnforced`), since PublicKeyCredential MUST be [=scoped=] to the [=RP ID=].
        - For the following, use only the `teeEnforced` authorization list if the RP wants to accept only keys from a
            trusted execution environment, otherwise use the union of `teeEnforced` and `softwareEnforced`.
            - The value in the `AuthorizationList.origin` field is equal to `KM_ORIGIN_GENERATED`.
            - The value in the `AuthorizationList.purpose` field is equal to `KM_PURPOSE_SIGN`.
    - If successful, return implementation-specific values representing [=attestation type=] [=Basic=] and [=attestation trust
        path=] |x5c|.

### Android Key Attestation Statement Certificate Requirements ### {#sctn-key-attstn-cert-requirements}

Android Key Attestation [=attestation certificate=]'s <dfn>android key attestation certificate extension
data</dfn> is identified by the OID "1.3.6.1.4.1.11129.2.1.17", and its schema is defined in the [Android developer documentation](https://developer.android.com/training/articles/security-key-attestation#certificate_schema).

## Android SafetyNet Attestation Statement Format ## {#sctn-android-safetynet-attestation}

When the [=authenticator=] is a [=platform authenticator=] on certain Android platforms, the attestation
statement may be based on the [SafetyNet API](https://developer.android.com/training/safetynet/attestation#compat-check-response). In
this case the [=authenticator data=] is completely controlled by the caller of the SafetyNet API (typically an application
running on the Android platform) and the attestation statement  provides some statements about the health of the platform
and the identity of the calling application
(see [SafetyNet Documentation](https://developer.android.com/training/safetynet/attestation.html) for more details).

: Attestation statement format identifier
:: android-safetynet

: Attestation types supported
:: [=Basic=]

: Syntax
:: The syntax of an Android Attestation statement is defined as follows:

    ```
    $$attStmtType //= (
                          fmt: "android-safetynet",
                          attStmt: safetynetStmtFormat
                      )

    safetynetStmtFormat = {
                              ver: text,
                              response: bytes
                          }
    ```

    The semantics of the above fields are as follows:

    : ver
    :: The version number of Google Play Services responsible for providing the SafetyNet API.

    : response
    :: The [=UTF-8 encoded=] result of the getJwsResult() call of the SafetyNet API. This value is a JWS [[!RFC7515]] object (see
        [SafetyNet online documentation](https://developer.android.com/training/safetynet/attestation#compat-check-response))
        in Compact Serialization.

: Signing procedure
:: Let |authenticatorData| denote the [=authenticator data for the attestation=], and let |clientDataHash| denote the
    [=hash of the serialized client data=].

    Concatenate |authenticatorData| and |clientDataHash|, perform SHA-256 hash of the concatenated string, and
    let the result of the hash form |attToBeSigned|.

    Request a SafetyNet attestation, providing |attToBeSigned| as the nonce value. Set |response| to the result, and |ver| to
    the version of Google Play Services running in the authenticator.

: Verification procedure
:: Given the [=verification procedure inputs=] |attStmt|, |authenticatorData| and |clientDataHash|, the [=verification procedure=] is
    as follows:
    - Verify that |attStmt| is valid CBOR conforming to the syntax defined above and perform CBOR decoding on it to extract the
        contained fields.
    - Verify that |response| is a valid SafetyNet response of version |ver|
        by following the steps indicated by the [SafetyNet online documentation](https://developer.android.com/training/safetynet/attestation.html#compat-check-response).
        As of this writing, there is only one format of the SafetyNet response and |ver| is reserved for future use.
    - Verify that the `nonce` attribute in the payload of |response| is identical to the Base64 encoding of the SHA-256 hash of the concatenation of |authenticatorData| and |clientDataHash|.
    - Verify that the SafetyNet response actually came from the SafetyNet service by following the steps in the
        [SafetyNet online documentation](https://developer.android.com/training/safetynet/attestation#compat-check-response).
    - If successful, return implementation-specific values representing [=attestation type=] [=Basic=] and [=attestation trust
        path=] |x5c|.


## FIDO U2F Attestation Statement Format ## {#sctn-fido-u2f-attestation}

This attestation statement format is used with FIDO U2F authenticators using the formats defined in
[[FIDO-U2F-Message-Formats]].

: Attestation statement format identifier
:: fido-u2f

: Attestation types supported
:: [=Basic=], [=AttCA=]

: Syntax
:: The syntax of a FIDO U2F attestation statement is defined as follows:

    ```
    $$attStmtType //= (
                          fmt: "fido-u2f",
                          attStmt: u2fStmtFormat
                      )

    u2fStmtFormat = {
                        x5c: [ attestnCert: bytes ],
                        sig: bytes
                    }
    ```

    The semantics of the above fields are as follows:

    : x5c
    :: A single element array containing the attestation certificate in X.509 format.

    : sig
    :: The [=attestation signature=].
        The signature was calculated over the (raw) U2F registration response message [[!FIDO-U2F-Message-Formats]]
        received by the [=client=] from the authenticator.

: Signing procedure
:: If the [=credential public key=] of the [=attestedCredentialData|attested credential=] is not of algorithm -7 ("ES256"), stop and return an error.
    Otherwise, let |authenticatorData| denote the [=authenticator data for the attestation=],
    and let |clientDataHash| denote the [=hash of the serialized client data=]. (Since SHA-256 is used to hash the
    serialized [=client data=], |clientDataHash| will be 32 bytes long.)

    Generate a Registration Response Message as specified in [[!FIDO-U2F-Message-Formats]] [=Section 4.3=], with the application parameter set to the
    SHA-256 hash of the [=RP ID=] that the given [=public key credential|credential=] is [=scoped=] to, the challenge parameter set to |clientDataHash|, and the key handle
    parameter set to the [=credential ID=] of the given credential. Set the raw signature part of this Registration Response Message (i.e., without the [=user public key=],
    key handle, and attestation certificates) as |sig| and set the attestation certificates of
    the attestation public key as |x5c|.

: Verification procedure
:: Given the [=verification procedure inputs=] |attStmt|, |authenticatorData| and |clientDataHash|, the [=verification procedure=] is
    as follows:
    1. Verify that |attStmt| is valid CBOR conforming to the syntax defined above and perform CBOR decoding on it to extract the
        contained fields.
    1. Check that |x5c| has exactly one element and let |attCert| be that element. Let |certificate public key| be the public key
        conveyed by |attCert|. If |certificate public key| is not an Elliptic Curve (EC) public
        key over the P-256 curve, terminate this algorithm and return an appropriate error.
    1. Extract the claimed |rpIdHash| from |authenticatorData|, and the claimed |credentialId| and |credentialPublicKey| from
        |authenticatorData|.<code>[=attestedCredentialData=]</code>.
    1. Convert the COSE_KEY formatted |credentialPublicKey| (see [=Section 7=] of [[!RFC8152]]) to Raw ANSI X9.62 public key
        format (see ALG_KEY_ECC_X962_RAW in [=Section 3.6.2 Public Key Representation Formats=] of [[!FIDO-Registry]]).
        - Let |x| be the value corresponding to the "-2" key (representing x coordinate) in |credentialPublicKey|, and confirm its
            size to be of 32 bytes.
            If size differs or "-2" key is not found, terminate this algorithm and return an appropriate error.
        - Let |y| be the value corresponding to the "-3" key (representing y coordinate) in |credentialPublicKey|, and confirm its
            size to be of 32 bytes.
            If size differs or "-3" key is not found, terminate this algorithm and return an appropriate error.
        - Let |publicKeyU2F| be the concatenation <code>0x04 || |x| || |y|</code>.

            Note: This signifies uncompressed ECC key format.
    1. Let |verificationData| be the concatenation of (0x00 || |rpIdHash| ||
        |clientDataHash| || |credentialId| || |publicKeyU2F|) (see [=Section 4.3=] of [[!FIDO-U2F-Message-Formats]]).
    1. Verify the |sig| using |verificationData| and the |certificate public key| per section 4.1.4 of [[!SEC1]] with SHA-256 as the hash function used in step two.
    1. Optionally, inspect |x5c| and consult externally provided knowledge to determine whether |attStmt| conveys a [=Basic=] or
        [=AttCA=] attestation.
    1. If successful, return implementation-specific values representing [=attestation type=] [=Basic=], [=AttCA=] or uncertainty,
        and [=attestation trust path=] |x5c|.

## None Attestation Statement Format ## {#sctn-none-attestation}

The none attestation statement format is used to replace any [=authenticator=]-provided [=attestation statement=] when a [=[WRP]=] indicates it does not wish to receive attestation information, see  [[#enum-attestation-convey]].

The [=authenticator=] MAY also directly generate attestation statements of this format
if the [=authenticator=] does not support [=attestation=].

: Attestation statement format identifier
:: none

: Attestation types supported
:: [=None=]

: Syntax
:: The syntax of a none attestation statement is defined as follows:

    ```
    $$attStmtType //= (
                          fmt: "none",
                          attStmt: emptyMap
                      )

    emptyMap = {}
    ```

: Signing procedure
:: Return the fixed attestation statement defined above.

: Verification procedure
:: Return implementation-specific values representing [=attestation type=] [=None=] and an empty [=attestation trust path=].

# <dfn>WebAuthn Extensions</dfn> # {#sctn-extensions}

The mechanism for generating [=public key credentials=], as well as requesting and generating Authentication assertions, as
defined in [[#sctn-api]], can be extended to suit particular use cases. Each case is addressed by defining a <dfn>registration
extension</dfn> and/or an <dfn>authentication extension</dfn>.

Every extension is a <dfn>client extension</dfn>, meaning that the extension involves communication with and processing by the
client.
[=Client extensions=] define the following steps and data:

- {{CredentialsContainer/create()|navigator.credentials.create()}} extension request parameters and response values for [=registration extensions=].

- {{CredentialsContainer/get()|navigator.credentials.get()}} extension request parameters and response values for [=authentication extensions=].

- [=Client extension processing=] for [=registration extensions=] and [=authentication extensions=].

When creating a [=public key credential=] or requesting an [=authentication assertion=], a [=[WRP]=] can request the use of a set
of extensions. These extensions will be invoked during the requested operation if they are supported by the client and/or the
[=[WAA]=]. The [=[RP]=] sends the [=client extension input=] for each extension in the {{CredentialsContainer/get()}} call
(for [=authentication extensions=]) or {{CredentialsContainer/create()}} call (for [=registration extensions=]) to the [=client=].
The [=client=] performs [=client extension processing=] for each extension that the [=client platform=] supports, and augments the
[=client data=] as specified by each extension, by including the [=extension identifier=] and [=client extension output=]
values.

An extension can also be an <dfn>authenticator extension</dfn>, meaning that the extension involves communication with and
processing by the authenticator. [=Authenticator extensions=] define the following steps and data:

- [=authenticatorMakeCredential=] extension request parameters and response values for [=registration extensions=].

- [=authenticatorGetAssertion=] extension request parameters and response values for [=authentication extensions=].

- [=Authenticator extension processing=] for [=registration extensions=] and [=authentication extensions=].

For [=authenticator extensions=], as part of the [=client extension processing=], the client also creates the [=CBOR=]
[=authenticator extension input=] value for each extension (often based on the corresponding [=client extension input=] value),
and passes them to the authenticator in the {{CredentialsContainer/create()}} call (for [=registration extensions=]) or the
{{CredentialsContainer/get()}} call (for [=authentication extensions=]). These [=authenticator extension input=] values are
represented in [=CBOR=] and passed as name-value pairs, with the [=extension identifier=] as the name, and the corresponding
[=authenticator extension input=] as the value. The authenticator, in turn, performs additional processing for the extensions
that it supports, and returns the [=CBOR=] [=authenticator extension output=] for each as specified by the extension. Part of
the [=client extension processing=] for [=authenticator extensions=] is to use the [=authenticator extension output=] as an
input to creating the [=client extension output=].

All [=WebAuthn Extensions=] are OPTIONAL for both clients and authenticators. Thus, any extensions requested by a [=[RP]=] MAY be
ignored by the client browser or OS and not passed to the authenticator at all, or they MAY be ignored by the authenticator.
Ignoring an extension is never considered a failure in WebAuthn API processing, so when [=[RPS]=] include extensions with any
API calls, they MUST be prepared to handle cases where some or all of those extensions are ignored.

Clients wishing to support the widest possible range of extensions MAY choose to pass through any extensions that they do not
recognize to authenticators, generating the [=authenticator extension input=] by simply encoding the [=client extension input=]
in CBOR. All [=WebAuthn Extensions=] MUST be defined in such a way that this implementation choice does not endanger the user's
security or privacy. For instance, if an extension requires client processing, it could be defined in a manner that ensures such
a naïve pass-through will produce a semantically invalid [=authenticator extension input=] value, resulting in the extension
being ignored by the authenticator. Since all extensions are OPTIONAL, this will not cause a functional failure in the API
operation. Likewise, clients can choose to produce a [=client extension output=] value for an extension that it does not
understand by encoding the [=authenticator extension output=] value into JSON, provided that the CBOR output uses only types
present in JSON.

When [=clients=] choose to pass through extensions they do not recognize,
the JavaScript values in the [=client extension inputs=]
are converted to [=CBOR=] values in the [=authenticator extension inputs=].
When the JavaScript value is an [=%ArrayBuffer%=], it is converted to a [=CBOR=] byte array.
When the JavaScript value is a non-integer number, it is converted to a 64-bit CBOR floating point number.
Otherwise, when the JavaScript type corresponds to a JSON type, the conversion is done
using the rules defined in Section 4.2 of [[!RFC7049]] (Converting from JSON to CBOR),
but operating on inputs of JavaScript type values rather than inputs of JSON type values.
Once these conversions are done,
canonicalization of the resulting [=CBOR=] MUST be performed using the [=CTAP2 canonical CBOR encoding form=].

Note that the JavaScript numeric conversion rules have the consequence that
when a client passes through an extension it does not recognize,
if the extension uses floating point values,
[=authenticators=] need to be prepared to receive those values as [=CBOR=] integers,
should the [=authenticator=] want the extension to always work without actual [=client=] support for it.
This will happen when the floating point values used happen to be integers.

Likewise, when clients receive outputs from extensions they have passed through that they do not recognize,
the [=CBOR=] values in the [=authenticator extension outputs=]
are converted to JavaScript values in the [=client extension outputs=].
When the CBOR value is a byte string, it is converted to a JavaScript [=%ArrayBuffer%=]
(rather than a base64url-encoded string).
Otherwise, when the CBOR type corresponds to a JSON type, the conversion is done
using the rules defined in Section 4.1 of [[!RFC7049]] (Converting from CBOR to JSON),
but producing outputs of JavaScript type values rather than outputs of JSON type values.

Note that some clients may choose to implement this pass-through capability under a feature flag.
Supporting this capability can facilitate innovation, allowing authenticators to experiment with new extensions
and [=[RPS]=] to use them before there is explicit support for them in clients.

The IANA "WebAuthn Extension Identifier" registry established by [[!WebAuthn-Registries]] can be consulted
for an up-to-date list of registered [=WebAuthn Extensions=].


## Extension Identifiers ## {#sctn-extension-id}

Extensions are identified by a string, called an <dfn>extension identifier</dfn>, chosen by the extension author.

Extension identifiers SHOULD be registered per [[!WebAuthn-Registries]] "Registries for Web Authentication (WebAuthn)".
All registered extension identifiers are unique amongst themselves as a matter of course.

Unregistered extension identifiers SHOULD aim to be globally unique, e.g., by including the defining entity such as
`myCompany_extension`.

All extension identifiers MUST be a maximum of 32 octets in length and MUST consist only of printable USASCII characters,
excluding backslash and doublequote, i.e., VCHAR as defined in [[!RFC5234]] but without %x22 and %x5c. Implementations MUST
match WebAuthn extension identifiers in a case-sensitive fashion.

Extensions that may exist in multiple versions should take care to include a version in their identifier. In effect, different
versions are thus treated as different extensions, e.g., `myCompany_extension_01`

[[#sctn-defined-extensions]] defines an initial set of extensions and their identifiers.
See the IANA "WebAuthn Extension Identifier" registry established by [[!WebAuthn-Registries]]
for an up-to-date list of registered WebAuthn Extension Identifiers.


## Defining Extensions ## {#sctn-extension-specification}

A definition of an extension MUST specify an [=extension identifier=], a [=client extension input=] argument
to be sent via the {{CredentialsContainer/get()}} or {{CredentialsContainer/create()}} call,
the [=client extension processing=] rules, and a [=client extension output=] value.
If the extension communicates with the authenticator (meaning it is an [=authenticator extension=]),
it MUST also specify the [=CBOR=] [=authenticator extension input=] argument
sent via the [=authenticatorGetAssertion=] or [=authenticatorMakeCredential=] call,
the [=authenticator extension processing=] rules, and the [=CBOR=] [=authenticator extension output=] value.

Any [=client extension=] that is processed by the client MUST return a [=client extension output=] value so that the [=[WRP]=]
knows that the extension was honored by the client. Similarly, any extension that requires authenticator processing MUST return
an [=authenticator extension output=] to let the [=[RP]=] know that the extension was honored by the authenticator. If an
extension does not otherwise require any result values, it SHOULD be defined as returning a JSON Boolean [=client extension
output=] result, set to [TRUE] to signify that the extension was understood and processed. Likewise, any [=authenticator
extension=] that does not otherwise require any result values MUST return a value and SHOULD return a CBOR Boolean
[=authenticator extension output=] result, set to [TRUE] to signify that the extension was understood and processed.


## Extending Request Parameters ## {#sctn-extension-request-parameters}

An extension defines one or two request arguments. The <dfn>client extension input</dfn>,
which is a value that can be encoded in JSON, is passed from the [=[WRP]=] to the client
in the {{CredentialsContainer/get()}} or {{CredentialsContainer/create()}} call,
while the [=CBOR=] <dfn>authenticator extension input</dfn> is
passed from the client to the authenticator for [=authenticator extensions=] during the processing of these calls.

A [=[RP]=] simultaneously requests the use of an extension and sets its [=client extension input=] by including an entry in the
{{PublicKeyCredentialCreationOptions/extensions}} option to the {{CredentialsContainer/create()}} or {{CredentialsContainer/get()}} call.
The entry key is the [=extension identifier=] and the value is the [=client extension input=].

<pre class="example" highlight="js">
    var assertionPromise = navigator.credentials.get({
        publicKey: {
            // The challenge is produced by the server; see the Security Considerations
            challenge: new Uint8Array([4,99,22 /* 29 more random bytes generated by the server */]),
            extensions: {
                "webauthnExample_foobar": 42
            }
        }
    });
</pre>

Extension definitions MUST specify the valid values for their [=client extension input=]. Clients SHOULD ignore extensions with
an invalid [=client extension input=]. If an extension does not require any parameters from the [=[RP]=], it SHOULD be defined
as taking a Boolean client argument, set to [TRUE] to signify that the extension is requested by the [=[RP]=].

Extensions that only affect client processing need not specify [=authenticator extension input=]. Extensions that have
authenticator processing MUST specify the method of computing the [=authenticator extension input=] from the [=client extension
input=]. For extensions that do not require input parameters and are defined as taking a Boolean [=client extension input=]
value set to [TRUE], this method SHOULD consist of passing an [=authenticator extension input=] value of [TRUE] (CBOR major type
7, value 21).

Note: Extensions should aim to define authenticator arguments that are as small as possible. Some authenticators communicate
    over low-bandwidth links such as Bluetooth Low-Energy or NFC.


## <dfn>Client Extension Processing</dfn> ## {#sctn-client-extension-processing}

Extensions MAY define additional processing requirements on the [=client=] during the creation of credentials or the
generation of an assertion. The [=client extension input=] for the extension is used as an input to this client processing.
For each supported [=client extension=], the client adds an entry to the |clientExtensions|  [=map=] with the
[=extension identifier=] as the key, and the extension's [=client extension input=] as the value.

Likewise, the [=client extension outputs=] are represented as a dictionary in the result of {{PublicKeyCredential/getClientExtensionResults()}}
with [=extension identifiers=] as keys, and the <dfn>client extension output</dfn> value of each extension as the value.
Like the [=client extension input=], the [=client extension output=] is a value that can be encoded in JSON.
There MUST NOT be any values returned for ignored extensions.

Extensions that require authenticator processing MUST define
the process by which the [=client extension input=] can be used to determine the [=CBOR=] [=authenticator extension input=] and
the process by which the [=CBOR=] [=authenticator extension output=] can be used to determine the [=client extension output=].

## <dfn>Authenticator Extension Processing</dfn> ## {#sctn-authenticator-extension-processing}

The [=CBOR=] [=authenticator extension input=] value of each processed [=authenticator extension=] is included in the |extensions|
parameter of the [=authenticatorMakeCredential=] and [=authenticatorGetAssertion=] operations. The |extensions| parameter is a
[=CBOR=] map where each key is an [=extension identifier=] and the corresponding value is the [=authenticator extension input=]
for that extension.

Likewise, the extension output is represented in the [=authdataextensions|extensions=] part of the [=authenticator data=]. The
[=authdataextensions|extensions=] part of the [=authenticator data=] is a CBOR map where each key is an [=extension identifier=]
and the corresponding value is the <dfn>authenticator extension output</dfn> for that extension.

For each supported extension, the [=authenticator extension processing=] rule for that extension is used create the
[=authenticator extension output=] from the [=authenticator extension input=] and possibly also other inputs.
There MUST NOT be any values returned for ignored extensions.


# Defined Extensions # {#sctn-defined-extensions}

This section defines the initial set of extensions to be registered in the
IANA "WebAuthn Extension Identifier" registry established by [[!WebAuthn-Registries]].
These MAY be implemented by user agents targeting broad interoperability.


## FIDO <dfn>AppID</dfn> Extension (appid) ## {#sctn-appid-extension}

This extension allows [=[WRPS]=] that have previously registered a
credential using the legacy FIDO U2F JavaScript API [[FIDOU2FJavaScriptAPI]] to request an [=assertion=]. The
FIDO APIs use an alternative identifier for [=[RPS]=] called an |AppID|
[[!FIDO-APPID]], and any credentials created using those APIs will be [=scoped=] to
that identifier. Without this extension, they would need to be re-registered in
order to be [=scoped=] to an [=RP ID=].

In addition to setting the {{AuthenticationExtensionsClientInputs/appid}} extension input,
using this extension requires some additional processing by the [=[RP]=]
in order to allow users to [=authentication|authenticate=] using their registered U2F credentials:

 1. List the desired U2F credentials in the {{PublicKeyCredentialRequestOptions/allowCredentials}} option
     of the {{CredentialsContainer/get()}} method:

     - Set the {{PublicKeyCredentialDescriptor/type}} members to {{PublicKeyCredentialType/public-key}}.
     - Set the {{PublicKeyCredentialDescriptor/id}} members to the respective U2F key handles of the desired credentials. Note that U2F key handles commonly use [=base64url encoding=] but must be decoded to their binary form when used in {{PublicKeyCredentialDescriptor/id}}.

     {{PublicKeyCredentialRequestOptions/allowCredentials}} MAY contain a mixture
     of both WebAuthn [=credential IDs=] and U2F key handles;
     stating the {{AuthenticationExtensionsClientInputs/appid}} via this extension
     does not prevent the user from using a WebAuthn-registered credential
     scoped to the [=RP ID=] stated in {{PublicKeyCredentialRequestOptions/rpId}}.

 1. When [verifying the assertion](#rp-op-verifying-assertion-step-rpid-hash), expect that the <code>[=rpIdHash=]</code>
     MAY be the hash of the |AppID| instead of the [=RP ID=].

This extension does not allow FIDO-compatible credentials to be created. Thus,
credentials created with WebAuthn are not backwards compatible with the FIDO
JavaScript APIs.

Note: {{AuthenticationExtensionsClientInputs/appid}} should be set to the AppID
that the [=[RP]=] *previously* used in the legacy FIDO APIs.
This might not be the same as the result of translating the [=[RP]=]'s WebAuthn [=RP ID=] to the AppID format,
e.g., the previously used AppID may have been "https://accounts.example.com"
but the currently used [=RP ID=] might be "example.com".

: Extension identifier
:: `appid`

: Operation applicability
:: [=authentication extension|Authentication=]

: Client extension input
:: A single USVString specifying a FIDO |AppID|.
    <xmp class="idl">
    partial dictionary AuthenticationExtensionsClientInputs {
      USVString appid;
    };
    </xmp>

: Client extension processing
::  1. Let |facetId| be the result of passing the caller's [=origin=] to the
        FIDO algorithm for [=determining the FacetID of a calling application=].
    1. Let |appId| be the extension input.
    1. Pass |facetId| and |appId| to the FIDO algorithm for [=determining if a
        caller's FacetID is authorized for an AppID=]. If that algorithm rejects
        |appId| then return a "{{SecurityError}}" {{DOMException}}.
    1. When [building allowCredentialDescriptorList](#allowCredentialDescriptorListCreation),
        if a U2F authenticator indicates that a credential is inapplicable (i.e. by
        returning `SW_WRONG_DATA`) then the client MUST retry with the U2F application
        parameter set to the SHA-256 hash of |appId|. If this results in an applicable
        credential, the client MUST include the credential in
        <var ignore>allowCredentialDescriptorList</var>. The value of |appId| then replaces the `rpId`
        parameter of [=authenticatorGetAssertion=].
    1. Let |output| be the Boolean value [FALSE].
    1. When [creating assertionCreationData](#assertionCreationDataCreation),
        if the [=assertion=] was created by a U2F authenticator with the U2F application parameter set to the SHA-256 hash of |appId|
        instead of the SHA-256 hash of the [=RP ID=], set |output| to [TRUE].

Note: In practice, several implementations do not implement steps four and onward of the
algorithm for [=determining if a caller's FacetID is authorized for an AppID=].
Instead, in step three, the comparison on the host is relaxed to accept hosts on the
[=same site=].

: Client extension output
:: Returns the value of |output|. If true, the |AppID| was used and thus, when [verifying the assertion](#rp-op-verifying-assertion-step-rpid-hash), the [=[RP]=] MUST expect the <code>[=rpIdHash=]</code> to be the hash of the |AppID|, not the [=RP ID=].

    <xmp class="idl">
    partial dictionary AuthenticationExtensionsClientOutputs {
      boolean appid;
    };
    </xmp>

: Authenticator extension input
:: None.

: Authenticator extension processing
:: None.

: Authenticator extension output
:: None.

## FIDO AppID Exclusion Extension (appidExclude) ## {#sctn-appid-exclude-extension}

This registration extension allows [=[WRPS]=] to exclude authenticators which contain specified credentials that were created with the legacy FIDO U2F JavaScript API [[FIDOU2FJavaScriptAPI]].

During a transition from the FIDO U2F JavaScript API, a [=[RP]=] may have a population of users with legacy credentials already registered. The [appid](#sctn-appid-extension) extension allows the sign-in flow to be transitioned smoothly but, when transitioning the registration flow, the [excludeCredentials](#dom-publickeycredentialcreationoptions-excludecredentials) field will not be effective in excluding authenticators with legacy credentials because its contents are taken to be WebAuthn credentials. This extension directs [=client platforms=] to consider the contents of [excludeCredentials](#dom-publickeycredentialcreationoptions-excludecredentials) as both WebAuthn and legacy FIDO credentials. Note that U2F key handles commonly use [=base64url encoding=] but must be decoded to their binary form when used in [excludeCredentials](#dom-publickeycredentialcreationoptions-excludecredentials).


: Extension identifier
:: `appidExclude`

: Operation applicability
:: [=registration extension|Registration=]

: Client extension input
:: A single USVString specifying a FIDO |AppID|.
    <xmp class="idl">
    partial dictionary AuthenticationExtensionsClientInputs {
      USVString appidExclude;
    };
    </xmp>

: Client extension processing
:: When [[#sctn-createCredential|creating a new credential]]:
        1. Just after [establishing the RP ID](#CreateCred-DetermineRpId) perform these steps:
            1. Let |facetId| be the result of passing the caller's [=origin=] to the FIDO algorithm
                for [=determining the FacetID of a calling application=].
            1. Let |appId| be the value of the extension input {{appidExclude}}.
            1. Pass |facetId| and |appId| to the FIDO algorithm for [=determining if a caller's
                FacetID is authorized for an AppID=]. If the latter algorithm rejects |appId| then
                return a "{{SecurityError}}" {{DOMException}} and terminate the
                [creating a new credential](#sctn-createCredential) algorithm as well as these steps.

                Note: In practice, several implementations do not implement steps four and onward of the algorithm for [=determining if a caller's FacetID is authorized for an AppID=]. Instead, in step three, the comparison on the host is relaxed to accept hosts on the [=same site=].

            1. Otherwise, continue with normal processing.

        1. Just prior to [invoking authenticatorMakeCredential](#CreateCred-InvokeAuthnrMakeCred) perform these steps:
            1. If |authenticator| supports the U2F protocol [[!FIDO-U2F-Message-Formats]], then [=list/for each=]
                [credential descriptor](#dictdef-publickeycredentialdescriptor) |C| in |excludeCredentialDescriptorList|:
                1. Check whether |C| was created using U2F on |authenticator| by sending a
                    `U2F_AUTHENTICATE` message to |authenticator|
                    whose "five parts" are set to the following values:

                        :   |control byte|
                        ::  `0x07` ("check-only")

                        :   <var ignore>challenge parameter</var>
                        ::  32 random bytes

                        :   <var ignore>application parameter</var>
                        ::  SHA-256 hash of |appId|

                        :   <var ignore>key handle length</var>
                        ::  The length of <code>|C|.{{PublicKeyCredentialDescriptor/id}}</code> (in bytes)

                        :   <var ignore>key handle</var>
                        ::  The value of <code>|C|.{{PublicKeyCredentialDescriptor/id}}</code>, i.e., the [=credential id=].

                1. If |authenticator| responds with `message:error:test-of-user-presence-required` (i.e., success):
                    cease normal processing of this |authenticator| and indicate in a platform-specific manner
                    that the authenticator is inapplicable. For example, this could be in the form of UI, or
                    could involve requesting [=user consent=] from |authenticator| and, upon receipt, treating
                    it as if the authenticator had returned {{InvalidStateError}}. Requesting [=user consent=]
                    can be accomplished by sending another `U2F_AUTHENTICATE` message to |authenticator| as
                    above except for setting |control byte| to `0x03` ("enforce-user-presence-and-sign"),
                    and ignoring the response.

            1. Continue with normal processing.

: Client extension output
:: None.

: Authenticator extension input
:: None.

: Authenticator extension processing
:: None.

: Authenticator extension output
:: None.

## Simple Transaction Authorization Extension (txAuthSimple) ## {#sctn-simple-txauth-extension}

This extension allows for a simple form of transaction authorization. A
[=[RP]=] can specify a prompt string, intended for display on a trusted device on the authenticator.

: Extension identifier
:: `txAuthSimple`

: Operation applicability
:: [=authentication extension|Authentication=]

: Client extension input
:: A single USVString prompt.
    <xmp class="idl">
    partial dictionary AuthenticationExtensionsClientInputs {
      USVString txAuthSimple;
    };
    </xmp>

: Client extension processing
:: None, except creating the authenticator extension input from the client extension input.

: Client extension output
:: Returns the authenticator extension output string UTF-8 decoded into a USVString.
    <xmp class="idl">
    partial dictionary AuthenticationExtensionsClientOutputs {
      USVString txAuthSimple;
    };
    </xmp>

: Authenticator extension input
:: The client extension input encoded as a CBOR text string (major type 3).

<pre>
CDDL:
txAuthSimpleInput = (tstr)
</pre>

: Authenticator extension processing
:: The authenticator MUST display the prompt to the user before performing either [=user verification=] or [=test of user
    presence=]. The authenticator MAY insert line breaks if needed.

: Authenticator extension output
:: A single CBOR string, representing the prompt as displayed (including any eventual line breaks).

<pre>
CDDL:
txAuthSimpleOutput = (tstr)
</pre>

## Generic Transaction Authorization Extension (txAuthGeneric) ## {#sctn-generic-txauth-extension}

This extension allows images to be used as transaction authorization prompts
as well. This allows authenticators without a font rendering engine to be used and also supports a richer visual appearance.

: Extension identifier
:: `txAuthGeneric`

: Operation applicability
:: [=authentication extension|Authentication=]

: Client extension input
:: A JavaScript object defined as follows:
    <xmp class="idl">
    dictionary txAuthGenericArg {
        required USVString contentType;    // MIME-Type of the content, e.g., "image/png"
        required ArrayBuffer content;
    };

    partial dictionary AuthenticationExtensionsClientInputs {
      txAuthGenericArg txAuthGeneric;
    };
    </xmp>

: Client extension processing
:: None, except creating the authenticator extension input from the client extension input.

: Client extension output
:: Returns the authenticator extension output value as an ArrayBuffer.
    <xmp class="idl">
    partial dictionary AuthenticationExtensionsClientOutputs {
      ArrayBuffer txAuthGeneric;
    };
    </xmp>

: Authenticator extension input
:: The client extension input encoded as a CBOR map.

: Authenticator extension processing
:: The authenticator MUST display the `content` to the user before performing either [=user verification=] or [=test of
    user presence=]. The authenticator MAY add other information below the `content`. No changes are allowed to the `content`
    itself, i.e., inside `content` boundary box.

: Authenticator extension output
:: The hash value of the `content` which was displayed. The authenticator MUST use the same hash algorithm as it uses for the
    signature itself.


## Authenticator Selection Extension (authnSel) ## {#sctn-authenticator-selection-extension}

This extension allows a [=[WRP]=] to guide the selection of the authenticator that will be leveraged when
creating the credential. It is intended primarily for [=[RPS]=] that wish to tightly control the experience around credential
creation.

: Extension identifier
:: `authnSel`

: Operation applicability
:: [=registration extension|Registration=]

: Client extension input
:: A sequence of AAGUIDs:

    <xmp class="idl">
    typedef sequence<AAGUID> AuthenticatorSelectionList;

    partial dictionary AuthenticationExtensionsClientInputs {
      AuthenticatorSelectionList authnSel;
    };
    </xmp>


    Each AAGUID corresponds to an authenticator model that is acceptable to the [=[RP]=] for this credential creation. The
    list is ordered by decreasing preference.

    An AAGUID is defined as an array containing the globally unique identifier of the authenticator model being sought.

    <xmp class="idl">
        typedef BufferSource      AAGUID;
    </xmp>

: Client extension processing
:: If the client supports the Authenticator Selection Extension, it MUST use the first available authenticator whose AAGUID is
    present in the {{AuthenticatorSelectionList}}. If none of the available authenticators match a provided AAGUID, the client
    MUST select an authenticator from among the available authenticators to generate the credential.

: Client extension output
:: Returns the value [TRUE] to indicate to the [=[RP]=] that the extension was acted upon.
    <xmp class="idl">
    partial dictionary AuthenticationExtensionsClientOutputs {
      boolean authnSel;
    };
    </xmp>

: Authenticator extension input
:: None.

: Authenticator extension processing
:: None.

: Authenticator extension output
:: None.

## Supported Extensions Extension (exts) ## {#sctn-supported-extensions-extension}

This extension enables the [=[WRP]=] to determine which extensions the authenticator supports.

: Extension identifier
:: `exts`

: Operation applicability
:: [=registration extension|Registration=]

: Client extension input
:: The Boolean value [TRUE] to indicate that this extension is requested by the [=[RP]=].
    <xmp class="idl">
    partial dictionary AuthenticationExtensionsClientInputs {
      boolean exts;
    };
    </xmp>

: Client extension processing
:: None, except creating the authenticator extension input from the client extension input.

: Client extension output
:: Returns the list of supported extensions as an array of [=extension identifier=] strings.
    <xmp class="idl">
    typedef sequence<USVString> AuthenticationExtensionsSupported;

    partial dictionary AuthenticationExtensionsClientOutputs {
      AuthenticationExtensionsSupported exts;
    };
    </xmp>

: Authenticator extension input
:: The Boolean value [TRUE], encoded in CBOR (major type 7, value 21).

: Authenticator extension processing
:: The [=authenticator=] sets the [=authenticator extension output=] to be a list of extensions that the authenticator supports, as
    defined below. This extension can be added to attestation objects.

: Authenticator extension output
:: The SupportedExtensions extension is a list (CBOR array) of [=extension identifier=] ([=UTF-8 encoded=]) strings.


## User Verification Index Extension (uvi) ## {#sctn-uvi-extension}

This extension enables use of a user verification index.

: Extension identifier
:: `uvi`

: Operation applicability
:: [=registration extension|Registration=] and [=authentication extension|Authentication=]

: Client extension input
:: The Boolean value [TRUE] to indicate that this extension is requested by the [=[RP]=].
    <xmp class="idl">
    partial dictionary AuthenticationExtensionsClientInputs {
      boolean uvi;
    };
    </xmp>

: Client extension processing
:: None, except creating the authenticator extension input from the client extension input.

: Client extension output
:: Returns the authenticator extension output as an ArrayBuffer.
    <xmp class="idl">
    partial dictionary AuthenticationExtensionsClientOutputs {
      ArrayBuffer uvi;
    };
    </xmp>

: Authenticator extension input
:: The Boolean value [TRUE], encoded in CBOR (major type 7, value 21).

: Authenticator extension processing
:: The [=authenticator=] sets the [=authenticator extension output=] to be a user verification index indicating the method used
    by the user to authorize the operation, as defined below. This extension can be added to attestation objects and assertions.

: Authenticator extension output
:: The user verification index (UVI) is a value uniquely identifying a user verification data record. The UVI is encoded as CBOR
    byte string (type 0x58). Each UVI value MUST be specific to the related key (in order to provide unlinkability). It also
    MUST contain sufficient entropy that makes guessing impractical. UVI values MUST NOT be reused by the Authenticator (for
    other biometric data or users).

    The UVI data can be used by servers to understand whether an authentication was authorized by the exact same biometric data
    as the initial key generation. This allows the detection and prevention of "friendly fraud".

    As an example, the UVI could be computed as SHA256(KeyID || SHA256(rawUVI)), where `||` represents concatenation, and the
    rawUVI reflects (a) the biometric reference data, (b) the related OS level user ID and (c) an identifier which changes
    whenever a factory reset is performed for the [=authenticator=], e.g. rawUVI = biometricReferenceData || OSLevelUserID ||
    FactoryResetCounter.

    Example of [=authenticator data=] containing one UVI extension
    <pre>
        ...                                         -- RP ID hash (32 bytes)
        81                                          -- UP and ED set
        00 00 00 01                                 -- (initial) signature counter
        ...                                         -- all public key alg etc.
        A1                                          -- extension: CBOR map of one element
            63                                      -- Key 1: CBOR text string of 3 bytes
                75 76 69                            -- "uvi" [=UTF-8 encoded=] string
            58 20                                   -- Value 1: CBOR byte string with 0x20 bytes
                43 B8 E3 BE 27 95 8C 28             -- the UVI value itself
                D5 74 BF 46 8A 85 CF 46
                9A 14 F0 E5 16 69 31 DA
                4B CF FF C1 BB 11 32 82
    </pre>

## Location Extension (loc) ## {#sctn-location-extension}

This extension provides the [=authenticator=]'s current geographic location to the [=[WRP]=].

<div class="note">
    Note: In almost all cases, this information also discloses the location of the user of the device,
    thereby potentially compromising the user's privacy. A [=conforming user agent=] MUST provide a mechanism that protects the user's privacy and this mechanism
    MUST ensure that no location information is made available through this API without the user's
    express permission [[Permissions]]. Further, the security and privacy considerations
    given in [[!Geolocation-API]] are applicable here and MUST be adhered to.
    See also [[#sctn-security-considerations-client]].

    The location data returned by this extension is conveyed within the
    signed [=authenticator extension output=], thus it is not possible to remove it from the
    response message's [=authenticator data=]'s [=authdataextensions|extensions=] member
    without causing the signature to fail subsequent validation. Implementers of this
    [=extension=], in the case where the user elects to not reveal their location, must therefore
    consider whether they will fail requests containing this extension, or remove the extension
    from requests.
</div>

: Extension identifier
:: `loc`

: Operation applicability
:: [=registration extension|Registration=] and [=authentication extension|Authentication=]

: Client extension input
:: The Boolean value [TRUE] to indicate that this extension is requested by the [=[RP]=].
    <xmp class="idl">
    partial dictionary AuthenticationExtensionsClientInputs {
      boolean loc;
    };
    </xmp>

: Client extension processing
:: None, except creating the authenticator extension input from the client extension input.

: Client extension output
:: Returns a JavaScript object that encodes the location information in the authenticator extension output as a {{GeolocationCoordinates}} value,
    as defined by [[!Geolocation-API]].
    <xmp class="idl">
    partial dictionary AuthenticationExtensionsClientOutputs {
      GeolocationCoordinates loc;
    };
    </xmp>

: Authenticator extension input
:: The Boolean value [TRUE], encoded in CBOR (major type 7, value 21).

: Authenticator extension processing
:: Determine the Geolocation value.

: Authenticator extension output
:: A
    [[!Geolocation-API]]
    {{GeolocationCoordinates}} record encoded as a CBOR map.
    Values represented by the "double" type in JavaScript are represented as 64-bit CBOR floating point numbers.
    Per the Geolocation specification, the "latitude", "longitude", and "accuracy" values are REQUIRED
    and other values such as "altitude" are OPTIONAL.

## User Verification Method Extension (uvm) ## {#sctn-uvm-extension}

This extension enables use of a user verification method.

: Extension identifier
:: `uvm`

: Operation applicability
:: [=registration extension|Registration=] and [=authentication extension|Authentication=]

: Client extension input
:: The Boolean value [TRUE] to indicate that this extension is requested by the [=[RP]=].
    <xmp class="idl">
    partial dictionary AuthenticationExtensionsClientInputs {
      boolean uvm;
    };
    </xmp>

: Client extension processing
:: None, except creating the authenticator extension input from the client extension input.

: Client extension output
:: Returns a JSON array of 3-element arrays of numbers that encodes the factors in the authenticator extension output.
    <xmp class="idl">
    typedef sequence<unsigned long> UvmEntry;
    typedef sequence<UvmEntry> UvmEntries;

    partial dictionary AuthenticationExtensionsClientOutputs {
      UvmEntries uvm;
    };
    </xmp>

: Authenticator extension input
:: The Boolean value [TRUE], encoded in CBOR (major type 7, value 21).

: Authenticator extension processing
:: The [=authenticator=] sets the [=authenticator extension output=] to be one or more user verification methods indicating the method(s) used
    by the user to authorize the operation, as defined below. This extension can be added to attestation objects and assertions.

: Authenticator extension output
:: Authenticators can report up to 3 different user verification methods (factors) used in a single authentication instance,
    using the CBOR syntax defined below:

    ```
    uvmFormat = [ 1*3 uvmEntry ]
    uvmEntry = [
                   userVerificationMethod: uint .size 4,
                   keyProtectionType: uint .size 2,
                   matcherProtectionType: uint .size 2
               ]
    ```

    The semantics of the fields in each `uvmEntry` are as follows:
    : userVerificationMethod
    :: The authentication method/factor used by the authenticator to verify the user. Available values are defined in
        [=Section 3.1 User Verification Methods=] of [[!FIDO-Registry]].

    : keyProtectionType
    :: The method used by the authenticator to protect the FIDO registration private key material. Available values are defined
        in [=Section 3.2 Key Protection Types=] of [[!FIDO-Registry]].

    : matcherProtectionType
    :: The method used by the authenticator to protect the matcher that performs user verification. Available values are defined
        in [=Section 3.3 Matcher Protection Types=] of [[!FIDO-Registry]].

    If >3 factors can be used in an authentication instance the authenticator vendor MUST select the 3 factors it believes
    will be most relevant to the Server to include in the UVM.

    Example for [=authenticator data=] containing one UVM extension for a multi-factor authentication instance where 2 factors
    were used:
    <pre>
        ...                    -- RP ID hash (32 bytes)
        81                     -- UP and ED set
        00 00 00 01            -- (initial) signature counter
        ...                    -- all public key alg etc.
        A1                     -- extension: CBOR map of one element
            63                 -- Key 1: CBOR text string of 3 bytes
                75 76 6d       -- "uvm" [=UTF-8 encoded=] string
            82                 -- Value 1: CBOR array of length 2 indicating two factor usage
                83              -- Item 1: CBOR array of length 3
                    02           -- Subitem 1: CBOR integer for User Verification Method Fingerprint
                    04           -- Subitem 2: CBOR short for Key Protection Type TEE
                    02           -- Subitem 3: CBOR short for Matcher Protection Type TEE
                83              -- Item 2: CBOR array of length 3
                    04           -- Subitem 1: CBOR integer for User Verification Method Passcode
                    01           -- Subitem 2: CBOR short for Key Protection Type Software
                    01           -- Subitem 3: CBOR short for Matcher Protection Type Software
    </pre>


## Biometric Authenticator Performance Bounds Extension (biometricPerfBounds) ## {#sctn-authenticator-biometric-criteria-extension}

This extension allows [=[WRPS]=] to specify the desired performance bounds for selecting [=biometric authenticators=]
as candidates to be employed in a [=registration ceremony=].

: Extension identifier
:: `biometricPerfBounds`

: Operation applicability
:: [=registration extension|Registration=]

: Client extension input
:: Biometric performance bounds:

    <xmp class="idl">
    dictionary AuthenticatorBiometricPerfBounds {
        float FAR;
        float FRR;
    };
    </xmp>

    The FAR is the maximum false acceptance rate for a biometric authenticator allowed by the [=[RP]=].

    The FRR is the maximum false rejection rate for a biometric authenticator allowed by the [=[RP]=].

: Client extension processing
:: If the client supports this extension, it MUST NOT use a biometric authenticator whose FAR or FRR does not match the
    bounds as provided.  The client can obtain information about the biometric authenticator's performance from authoritative
    sources such as the FIDO Metadata Service [[FIDOMetadataService]] (see Sec. 3.2 of [[FIDOUAFAuthenticatorMetadataStatements]]).

: Client extension output
:: Returns the JSON value [TRUE] to indicate to the [=[RP]=] that the extension was acted upon

: Authenticator extension input
:: None.

: Authenticator extension processing
:: None.

: Authenticator extension output
:: None.


## Credential Properties Extension (<dfn>credProps</dfn>) ## {#sctn-authenticator-credential-properties-extension}

This [=client extension|client=] [=registration extension=] facilitates reporting certain [=credential properties=] known by the [=client=] to the requesting [=[WRP]=] upon creation of a [=public key credential source=] as a result of a [=registration ceremony=].

At this time, one [=credential property=] is defined: the [=resident key credential property=].

: Extension identifier
:: `credProps`

: Operation applicability
:: [=registration extension|Registration=]

: Client extension input
:: The Boolean value [TRUE] to indicate that this extension is requested by the [=[RP]=].
    <xmp class="idl">
    partial dictionary AuthenticationExtensionsClientInputs {
        boolean credProps;
    };
    </xmp>

: Client extension processing
::  None, other than to report on credential properties in the output.

: Client extension output
:: [=map/Set=] <code>[=credentialCreationData/clientExtensionResults=]["{{AuthenticationExtensionsClientOutputs/credProps}}"]["rk"]</code> to the value of the |requireResidentKey| parameter that was used in the <a href='#CreateCred-InvokeAuthnrMakeCred'>invocation</a> of the [=authenticatorMakeCredential=] operation.

    <xmp class="idl">
    dictionary CredentialPropertiesOutput {
        boolean rk;
    };

    partial dictionary AuthenticationExtensionsClientOutputs {
        CredentialPropertiesOutput credProps;
    };
    </xmp>

    <div dfn-type="dict-member" dfn-for="CredentialPropertiesOutput">
        :   <dfn>rk</dfn>
        ::  This OPTIONAL property, known abstractly as the <dfn dfn-type="dfn">resident key credential property</dfn>,
            is a Boolean value indicating whether the {{PublicKeyCredential}} returned as a result of a [=registration ceremony=]
            is a [=resident credential=].
            If {{rk}} is [TRUE], the credential is a [=resident credential=];
            if {{rk}} is [FALSE], the credential is a [=non-resident credential=].
            If {{rk}} is [=not present=], it is not known whether the credential is a [=resident credential=] or a [=non-resident credential=].
    </div>


: Authenticator extension input
:: None.

: Authenticator extension processing
:: None.

: Authenticator extension output
:: None.


# User Agent Automation # {#sctn-automation}

For the purposes of user agent automation and [=web application=] testing, this document defines a number of [[WebDriver]] [=extension commands=].

## <dfn>Virtual Authenticators</dfn> ## {#sctn-automation-virtual-authenticators}

These WebDriver [=extension commands=] create and interact with [=Virtual Authenticators=]: software implementations of the
<a>Authenticator Model</a>. <a>Virtual Authenticators</a> are stored in a <dfn>Virtual Authenticator Database</dfn>.
Each stored [=virtual authenticator=] has the following properties:

: <dfn>authenticatorId</dfn>
:: An non-null string made using up to 48 characters from the `unreserved` production defined in Appendix A of [[RFC3986]]
    that uniquely identifies the [=Virtual Authenticator=].
: |protocol|
:: The protocol the [=Virtual Authenticator=] speaks: either `ctap2` or `ctap1/u2f` [[FIDO-CTAP]].
: |transport|
:: The {{AuthenticatorTransport}} simulated. If the |transport| is set to {{AuthenticatorTransport/internal}}, the
    authenticator simulates [=platform attachment=]. Otherwise, it simulates [=cross-platform attachment=].
: |hasResidentKey|
:: If set to [TRUE] the authenticator will support [=resident credentials=].
: |hasUserVerification|
:: If set to [TRUE], the authenticator supports [=user verification=].
: |isUserConsenting|
:: Determines the result of all [=user consent=] [=authorization gestures=], and by extension, any [=test of user presence=]
    performed on the [=Virtual Authenticator=]. If set to [TRUE], a [=user consent=] will always be granted. If set to
    [FALSE], it will not be granted.
: |isUserVerified|
:: Determines the result of [=User Verification=] performed on the [=Virtual Authenticator=]. If set to [TRUE],
    [=User Verification=] will always succeed. If set to [FALSE], it will fail.

    Note: This property has no effect if |hasUserVerification| is set to [FALSE].

## <dfn>Add Virtual Authenticator</dfn> ## {#sctn-automation-add-virtual-authenticator}

The [=Add Virtual Authenticator=] WebDriver [=extension command=] creates a software [=Virtual Authenticator=]. It is
defined as follows:

<figure id="table-addVirtualAuthenticator" class="table">
    <table class="data">
        <thead>
            <tr>
                <th>HTTP Method</th>
                <th>URI Template</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>POST</td>
                <td>`/session/{session id}/webauthn/authenticator`</td>
            </tr>
        </tbody>
    </table>
</figure>

The <dfn>Authenticator Configuration</dfn> is a JSON [=Object=] passed to the [=remote end steps=] as |parameters|. It contains the following |key| and |value| pairs:

<figure id="table-authenticatorConfiguration" class="table">
    <table class="data">
        <thead>
            <tr>
                <th>Key</th>
                <th>Value Type</th>
                <th>Valid Values</th>
                <th>Default</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>|protocol|</td>
                <td>string</td>
                <td>`"ctap1/u2f"`, `"ctap2"`</td>
                <td>None</td>
            </tr>
            <tr>
                <td>|transport|</td>
                <td>string</td>
                <td>{{AuthenticatorTransport}} values</td>
                <td>None</td>
            </tr>
            <tr>
                <td>|hasResidentKey|</td>
                <td>boolean</td>
                <td>[TRUE], [FALSE]</td>
                <td>[FALSE]</td>
            </tr>
            <tr>
                <td>|hasUserVerification|</td>
                <td>boolean</td>
                <td>[TRUE], [FALSE]</td>
                <td>[FALSE]</td>
            </tr>
            <tr>
                <td>|isUserConsenting|</td>
                <td>boolean</td>
                <td>[TRUE], [FALSE]</td>
                <td>[TRUE]</td>
            </tr>
            <tr>
                <td>|isUserVerified|</td>
                <td>boolean</td>
                <td>[TRUE], [FALSE]</td>
                <td>[FALSE]</td>
            </tr>
        </tbody>
    </table>
</figure>

The [=remote end steps=] are:

 1. If |parameters| is not a JSON [=Object=], return a [=WebDriver error=] with [=WebDriver error code=]
     [=invalid argument=].

     Note: |parameters| is a [=Authenticator Configuration=] object.
 1. Let |authenticator| be a new [=Virtual Authenticator=].
 1. For each enumerable [=own property=] in |parameters|:
    1. Let |key| be the name of the property.
    1. Let |value| be the result of [=getting a property=] named |key| from |parameters|.
    1. If there is no matching `key` for |key| in |parameters|, return a [=WebDriver error=] with
        [=WebDriver error code=] [=invalid argument=].
    1. If |value| is not one of the `valid values` for that |key|, return a [=WebDriver error=] with [=WebDriver error code=]
        [=invalid argument=].
    1. [=Set a property=] |key| to |value| on |authenticator|.
 1. For each property in [=Authenticator Configuration=] with a default defined:
    1. If `key` is not a defined property of |authenticator|, [=set a property=] `key` to `default` on |authenticator|.
 1. For each property in [=Authenticator Configuration=]:
    1. If `key` is not a defined property of |authenticator|, return a [=WebDriver error=] with [=WebDriver error code=]
        [=invalid argument=].
 1. Generate a valid unique [=authenticatorId=].
 1. [=Set a property=] `authenticatorId` to |authenticatorId| on |authenticator|.
 1. Store |authenticator| in the [=Virtual Authenticator Database=].
 1. Return [=success=] with data |authenticatorId|.

## <dfn>Remove Virtual Authenticator</dfn> ## {#sctn-automation-remove-virtual-authenticator}

The [=Remove Virtual Authenticator=] WebDriver [=extension command=] removes a previously created [=Virtual Authenticator=].
It is defined as follows:

<figure id="table-removeVirtualAuthenticator" class="table">
    <table class="data">
        <thead>
            <tr>
                <th>HTTP Method</th>
                <th>URI Template</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>DELETE</td>
                <td>`/session/{session id}/webauthn/authenticator/{authenticatorId}`</td>
            </tr>
        </tbody>
    </table>
</figure>

The [=remote end steps=] are:

 1. If |authenticatorId| does not match any [=Virtual Authenticator=] stored in the [=Virtual Authenticator
     Database=], return a [=WebDriver error=] with [=WebDriver error code=] [=invalid argument=].
 1. Remove the [=Virtual Authenticator=] identified by |authenticatorId| from the [=Virtual Authenticator Database=]
 1. Return [=success=].

## <dfn>Add Credential</dfn> ## {#sctn-automation-add-credential}

The [=Add Credential=] WebDriver [=extension command=] injects a [=Public Key Credential Source=] into an existing
[=Virtual Authenticator=]. It is defined as follows:

<figure id="table-addCredential" class="table">
    <table class="data">
        <thead>
            <tr>
                <th>HTTP Method</th>
                <th>URI Template</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>POST</td>
                <td>`/session/{session id}/webauthn/authenticator/{authenticatorId}/credential`</td>
            </tr>
        </tbody>
    </table>
</figure>

The <dfn>Credential Parameters</dfn> is a JSON [=Object=] passed to the [=remote end steps=] as |parameters|. It contains the following |key| and |value| pairs:

<figure id="table-credentialParameters" class="table">
    <table class="data">
        <thead>
            <tr>
                <th>Key</th>
                <th>Description</th>
                <th>Value Type</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>|credentialId|</td>
                <td>The [=public key credential source/id|Credential ID=] encoded using [=Base64url Encoding=].</td>
                <td>string</td>
            </tr>
            <tr>
                <td>|isResidentCredential|</td>
                <td>
                    If set to [TRUE], a [=resident credential=] is created. If set to [FALSE], a [=non-resident credential=]
                    is created instead.
                </td>
                <td>boolean</td>
            </tr>
            <tr>
                <td>|rpId|</td>
                <td>The [=public key credential source/rpId|Relying Party ID=] the credential is scoped to.</td>
                <td>string</td>
            </tr>
            <tr>
                <td>|privateKey|</td>
                <td>
                    An asymmetric key package containing a single [=public key credential source/privateKey|private key=]
                    per [[RFC5958]], encoded using [=Base64url Encoding=].
                </td>
                <td>string</td>
            </tr>
            <tr>
                <td>|userHandle|</td>
                <td>
                    The [=public key credential source/userHandle=] associated to the credential encoded using
                    [=Base64url Encoding=]. This property may not be defined.
                </td>
                <td>string</td>
            </tr>
            <tr>
                <td>|signCount|</td>
                <td>The initial value for a [=signature counter=] associated to the [=public key credential source=].</td>
                <td>number</td>
            </tr>
        </tbody>
    </table>
</figure>

The [=remote end steps=] are:

 1. If |parameters| is not a JSON [=Object=], return a [=WebDriver error=] with [=WebDriver error code=]
     [=invalid argument=].

     Note: |parameters| is a [=Credential Parameters=] object.
 1. Let |credentialId| be the result of decoding [=Base64url Encoding=] on the |parameters|' |credentialId| property.
 1. If |credentialId| is failure, return a [=WebDriver error=] with [=WebDriver error code=] [=invalid argument=].
 1. Let |isResidentCredential| be the |parameters|' |isResidentCredential| property.
 1. If |isResidentCredential| is not defined, return a [=WebDriver error=] with [=WebDriver error code=] [=invalid argument=].
 1. Let |rpId| be the |parameters|' |rpId| property.
 1. If |rpId| is not a valid [=RP ID=], return a [=WebDriver error=] with [=WebDriver error code=] [=invalid argument=].
 1. Let |privateKey| be the result of decoding [=Base64url Encoding=] on the |parameters|' |privateKey| property.
 1. If |privateKey| is failure, return a [=WebDriver error=] with [=WebDriver error code=] [=invalid argument=].
 1. If |privateKey| is not a validly-encoded asymmetric key package containing a single ECDSA private key on the P-256
     curve per [[RFC5958]], return a [=WebDriver error=] with [=WebDriver error code=] [=invalid argument=].
 1. If the |parameters|' |userHandle| property is defined:
     1. Let |userHandle| be the result of decoding [=Base64url Encoding=] on the |parameters|' |userHandle| property.
     1. If |userHandle| is failure, return a [=WebDriver error=] with [=WebDriver error code=] [=invalid argument=].
 1. Otherwise:
    1. If |isResidentCredential| is [TRUE], return a [=WebDriver error=] with [=WebDriver error code=] [=invalid argument=].
    1. Let |userHandle| be `null`.
 1. If |authenticatorId| does not match any [=Virtual Authenticator=] stored in the [=Virtual Authenticator
     Database=], return a [=WebDriver error=] with [=WebDriver error code=] [=invalid argument=].
 1. Let |authenticator| be the [=Virtual Authenticator=] matched by |authenticatorId|.
 1. If |isResidentCredential| is [TRUE] and the |authenticator|'s |hasResidentKey| property is [FALSE], return a
     [=WebDriver error=] with [=WebDriver error code=] [=invalid argument=].
 1. Let |credential| be a new [=Client-side-resident Public Key Credential Source=] if |isResidentCredential| is [TRUE]
     or a [=Server-side-resident Public Key Credential Source=] otherwise whose items are:
    : [=public key credential source/type=]
    :: {{public-key}}
    : [=public key credential source/id=]
    :: |credentialId|
    : [=public key credential source/privateKey=]
    :: |privateKey|
    : [=public key credential source/rpId=]
    :: |rpId|
    : [=public key credential source/userHandle=]
    :: |userHandle|
 1. Associate a [=signature counter=] |counter| to the |credential| with a starting value equal to the |parameters|'
     |signCount| or `0` if |signCount| is `null`.
 1. Store the |credential| and |counter| in the database of the |authenticator|.
 1. Return [=success=].

## <dfn>Get Credentials</dfn> ## {#sctn-automation-get-credentials}

The [=Get Credentials=] WebDriver [=extension command=] returns one [=Credential Parameters=] object for every
[=Public Key Credential Source=] stored in a [=Virtual Authenticator=], regardless of whether they were
stored using [=Add Credential=] or {{CredentialsContainer/create()|navigator.credentials.create()}}. It is defined as follows:

<figure id="table-getCredentials" class="table">
    <table class="data">
        <thead>
            <tr>
                <th>HTTP Method</th>
                <th>URI Template</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>GET</td>
                <td>`/session/{session id}/webauthn/authenticator/{authenticatorId}/credentials`</td>
            </tr>
        </tbody>
    </table>
</figure>

The [=remote end steps=] are:

 1. If |authenticatorId| does not match any [=Virtual Authenticator=] stored in the [=Virtual Authenticator
     Database=], return a [=WebDriver error=] with [=WebDriver error code=] [=invalid argument=].
 1. Let |credentialsArray| be an empty array.
 1. For each [=Public Key Credential Source=] |credential|, managed by the authenticator identified by |authenticatorId|,
    construct a corresponding [=Credential Parameters=] [=Object=] and add it to |credentialsArray|.
 1. Return [=success=] with data containing |credentialsArray|.

## <dfn>Remove Credential</dfn> ## {#sctn-automation-remove-credential}

The [=Remove Credential=] WebDriver [=extension command=] removes a [=Public Key Credential Source=] stored on a
[=Virtual Authenticator=]. It is defined as follows:

<figure id="table-removeCredential" class="table">
    <table class="data">
        <thead>
            <tr>
                <th>HTTP Method</th>
                <th>URI Template</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>DELETE</td>
                <td>`/session/{session id}/webauthn/authenticator/{authenticatorId}/credentials/{credentialId}`</td>
            </tr>
        </tbody>
    </table>
</figure>

The [=remote end steps=] are:

 1. If |authenticatorId| does not match any [=Virtual Authenticator=] stored in the [=Virtual Authenticator
     Database=], return a [=WebDriver error=] with [=WebDriver error code=] [=invalid argument=].
 1. Let |authenticator| be the [=Virtual Authenticator=] identified by |authenticatorId|.
 1. If |credentialId| does not match any [=Public Key Credential Source=] managed by |authenticator|, return a [=WebDriver error=]
     with [=WebDriver error code=] [=invalid argument=].
 1. Remove the [=Public Key Credential Source=] identified by |credentialId| managed by |authenticator|.
 1. Return [=success=].

## <dfn>Remove All Credentials</dfn> ## {#sctn-automation-remove-all-credentials}

The [=Remove All Credentials=] WebDriver [=extension command=] removes all [=Public Key Credential Sources=] stored on a
[=Virtual Authenticator=]. It is defined as follows:

<figure id="table-removeAllCredentials" class="table">
    <table class="data">
        <thead>
            <tr>
                <th>HTTP Method</th>
                <th>URI Template</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>DELETE</td>
                <td>`/session/{session id}/webauthn/authenticator/{authenticatorId}/credentials`</td>
            </tr>
        </tbody>
    </table>
</figure>

The [=remote end steps=] are:

 1. If |authenticatorId| does not match any [=Virtual Authenticator=] stored in the [=Virtual Authenticator
     Database=], return a [=WebDriver error=] with [=WebDriver error code=] [=invalid argument=].
 1. Remove all [=Public Key Credential Sources=] managed by the [=Virtual Authenticator=] identified by |authenticatorId|.
 1. Return [=success=].

## <dfn>Set User Verified</dfn> ## {#sctn-automation-set-user-verified}

The [=Set User Verified=] [=extension command=] sets the |isUserVerified| property on the [=Virtual Authenticator=]. It
is defined as follows:

<figure id="table-setUserVerified" class="table">
    <table class="data">
        <thead>
            <tr>
                <th>HTTP Method</th>
                <th>URI Template</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>POST</td>
                <td>`/session/{session id}/webauthn/authenticator/{authenticatorId}/uv`</td>
            </tr>
        </tbody>
    </table>
</figure>

The [=remote end steps=] are:

 1. If |parameters| is not a JSON [=Object=], return a [=WebDriver error=] with [=WebDriver error code=]
     [=invalid argument=].
 1. If |authenticatorId| does not match any [=Virtual Authenticator=] stored in the [=Virtual Authenticator
     Database=], return a [=WebDriver error=] with [=WebDriver error code=] [=invalid argument=].
 1. If |isUserVerified| is not a defined property of |parameters|, return a [=WebDriver error=] with [=WebDriver error code=]
     [=invalid argument=].
 1. Let |authenticator| be the [=Virtual Authenticator=] identified by |authenticatorId|.
 1. Set the |authenticator|'s |isUserVerified| property to the |parameters|' |isUserVerified| property.
 1. Return [=success=].

# IANA Considerations # {#sctn-IANA}

## WebAuthn Attestation Statement Format Identifier Registrations ## {#sctn-att-fmt-reg}

This section registers the attestation statement formats defined in Section [[#sctn-defined-attestation-formats]] in the
IANA "WebAuthn Attestation Statement Format Identifier" registry established by [[!WebAuthn-Registries]].

- WebAuthn Attestation Statement Format Identifier: packed
- Description: The "packed" attestation statement format is a WebAuthn-optimized format for [=attestation=]. It uses a very
    compact but still extensible encoding method. This format is implementable by authenticators with limited resources (e.g.,
    secure elements).
- Specification Document: Section [[#sctn-packed-attestation]] of this specification
    <br/><br/>
- WebAuthn Attestation Statement Format Identifier: tpm
- Description: The TPM attestation statement format returns an attestation statement in the same format as the packed
    attestation statement format, although the rawData and signature fields are computed differently.
- Specification Document: Section [[#sctn-tpm-attestation]] of this specification
    <br/><br/>
- WebAuthn Attestation Statement Format Identifier: android-key
- Description: [=Platform authenticators=] on versions "N", and later, may provide this proprietary "hardware
    attestation" statement.
- Specification Document: Section [[#sctn-android-key-attestation]] of this specification
    <br/><br/>
- WebAuthn Attestation Statement Format Identifier: android-safetynet
- Description: Android-based [=platform authenticators=] MAY produce an attestation statement based on the Android
    SafetyNet API.
- Specification Document: Section [[#sctn-android-safetynet-attestation]] of this specification
    <br/><br/>
- WebAuthn Attestation Statement Format Identifier: fido-u2f
- Description: Used with FIDO U2F authenticators
- Specification Document: Section [[#sctn-fido-u2f-attestation]] of this specification

## WebAuthn Extension Identifier Registrations ## {#sctn-extensions-reg}

This section registers the [=extension identifier=] values defined in Section [[#sctn-extensions]] in the
IANA "WebAuthn Extension Identifier" registry established by [[!WebAuthn-Registries]].

- WebAuthn Extension Identifier: appid
- Description: This [=authentication extension=] allows [=[WRPS]=] that have previously registered a credential using the legacy
    FIDO U2F JavaScript API [[FIDOU2FJavaScriptAPI]] to request an assertion.
- Specification Document: Section [[#sctn-appid-extension]] of this specification
    <br/><br/>
- WebAuthn Extension Identifier: txAuthSimple
- Description: This [=registration extension=] and [=authentication extension=] allows for a simple form of transaction
    authorization. A WebAuthn Relying Party can specify a prompt string, intended for display on a trusted device on the
    authenticator
- Specification Document: Section [[#sctn-simple-txauth-extension]] of this specification
    <br/><br/>
- WebAuthn Extension Identifier: txAuthGeneric
- Description: This [=registration extension=] and [=authentication extension=] allows images to be used as transaction
    authorization prompts as well. This allows authenticators without a font rendering engine to be used and also supports a
    richer visual appearance than accomplished with the webauthn.txauth.simple extension.
- Specification Document: Section [[#sctn-generic-txauth-extension]] of this specification
    <br/><br/>
- WebAuthn Extension Identifier: authnSel
- Description: This [=registration extension=] allows a WebAuthn Relying Party to guide the selection of the authenticator that
    will be leveraged when creating the credential. It is intended primarily for [=[WRPS]=] that wish to tightly
    control the experience around credential creation.
- Specification Document: Section [[#sctn-authenticator-selection-extension]] of this specification
    <br/><br/>
- WebAuthn Extension Identifier: exts
- Description: This [=registration extension=] enables the [=[WRP]=] to determine which extensions the authenticator supports. The
    extension data is a list (CBOR array) of extension identifiers encoded as UTF-8 Strings. This extension is added
    automatically by the authenticator. This extension can be added to attestation statements.
- Specification Document: Section [[#sctn-supported-extensions-extension]] of this specification
    <br/><br/>
- WebAuthn Extension Identifier: uvi
- Description: This [=registration extension=] and [=authentication extension=] enables use of a user verification index. The
    user verification index is a value uniquely identifying a user verification data record. The UVI data can be used by servers
    to understand whether an authentication was authorized by the exact same biometric data as the initial key generation. This
    allows the detection and prevention of "friendly fraud".
- Specification Document: Section [[#sctn-uvi-extension]] of this specification
    <br/><br/>
- WebAuthn Extension Identifier: loc
- Description: The location [=registration extension=] and [=authentication extension=] provides the [=client device=]'s current
    location to the [=[WRP]=], if supported by the [=client platform=] and subject to [=user consent=].
- Specification Document: Section [[#sctn-location-extension]] of this specification
    <br/><br/>
- WebAuthn Extension Identifier: uvm
- Description: This [=registration extension=] and [=authentication extension=] enables use of a user verification method.
    The user verification method extension returns to the [=[WRP]=] which user verification methods (factors) were
    used for the WebAuthn operation.
- Specification Document: Section [[#sctn-uvm-extension]] of this specification
    <br/><br/>
- WebAuthn Extension Identifier: credProps
- Description: This [=client extension|client=] [=registration extension=] enables reporting of a newly-created [=credential=]'s properties,
    as determined by the [=client=], to the calling [=[WRP]=]'s [=web application=].
- Specification Document: Section [[#sctn-authenticator-credential-properties-extension]] of this specification
    <br/><br/>

## COSE Algorithm Registrations ## {#sctn-cose-alg-reg}

This section registers identifiers for the following ECDAA algorithms in the
IANA COSE Algorithms registry [[!IANA-COSE-ALGS-REG]].
Note that [[!WebAuthn-COSE-Algs]] also registers
RSASSA-PKCS1-v1_5 [[RFC8017]] algorithms using SHA-2 and SHA-1 hash functions in the
IANA COSE Algorithms registry [[!IANA-COSE-ALGS-REG]],
such as registering -257 for "RS256".

- Name: ED256
- Value: TBD (requested assignment -260)
- Description: TPM_ECC_BN_P256 curve w/ SHA-256
- Reference: Section 4.2 of [[!FIDOEcdaaAlgorithm]]
- Recommended: Yes
    <br/><br/>
- Name: ED512
- Value: TBD (requested assignment -261)
- Description: ECC_BN_ISOP512 curve w/ SHA-512
- Reference: Section 4.2 of [[!FIDOEcdaaAlgorithm]]
- Recommended: Yes


# Security Considerations # {#sctn-security-considerations}

This specification defines a [[#sctn-api|Web API]] and a cryptographic peer-entity authentication protocol.
The [=Web Authentication API=] allows Web developers (i.e., "authors") to utilize the Web Authentication protocol in their
[=registration=] and [=authentication=] [=ceremonies=].
The entities comprising the Web Authentication protocol endpoints are user-controlled [=[WAA]s=] and a [=[WRP]=]'s
computing environment hosting the [=[RP]=]'s [=web application=].
In this model, the user agent, together with the [=[WAC]=], comprise an intermediary between [=authenticators=] and [=[RPS]=].
Additionally, [=authenticators=] can [=attestation|attest=] to [=[RPS]=] as to their provenance.

At this time, this specification does not feature detailed security considerations. However, the [[FIDOSecRef]] document provides a security analysis which is overall applicable to this specification.
Also, the [[FIDOAuthnrSecReqs]] document suite provides useful information about [=authenticator=] security characteristics.

The below subsections comprise the current Web Authentication-specific security considerations.
They are divided by audience;
general security considerations are direct subsections of this section,
while security considerations specifically for [=authenticator=], [=client=] and [=[RP]=] implementers
are grouped into respective subsections.


## Credential ID Unsigned ## {#sctn-credentialIdSecurity}

The [=credential ID=] is not signed.
This is not a problem because all that would happen if an [=authenticator=] returns
the wrong [=credential ID=], or if an attacker intercepts and manipulates the [=credential ID=], is that the [=[WRP]=] would not look up the correct
[=credential public key=] with which to verify the returned signed [=authenticator data=]
(a.k.a., [=assertion=]), and thus the interaction would end in an error.


## Security considerations for [=authenticators=] <span id="sctn-attestation-security-considerations"></span> ## {#sctn-security-considerations-authenticator}
<!-- Note: the above <span> is there to preserve the #sctn-attestation-security-considerations anchor although the section it was
tied to has been removed. The section had no text of its own and served only to group the following two subsections together. -->

### Attestation Certificate Hierarchy ### {#sctn-cert-hierarchy}

A 3-tier hierarchy for attestation certificates is RECOMMENDED (i.e., Attestation Root, Attestation Issuing CA, Attestation
Certificate). It is also RECOMMENDED that for each [=[WAA]=] device line (i.e., model), a separate issuing CA is
used to help facilitate isolating problems with a specific version of an authenticator model.

If the attestation root certificate is not dedicated to a single [=[WAA]=] device line (i.e., AAGUID), the AAGUID
SHOULD be specified in the attestation certificate itself, so that it can be verified against the [=authenticator data=].


### Attestation Certificate and Attestation Certificate CA Compromise ### {#sctn-ca-compromise}

When an intermediate CA or a root CA used for issuing attestation certificates is compromised, [=[WAA]=]
[=attestation key pairs=] are still safe although their certificates can no longer be trusted. A [=[WAA]=] manufacturer that
has recorded the [=attestation public keys=] for their [=authenticator=] models can issue new [=attestation certificates=] for these keys from a new
intermediate CA or from a new root CA. If the root CA changes, the [=[WRPS]=]  MUST update their trusted root certificates
accordingly.

A [=[WAA]=] [=attestation certificate=] MUST be revoked by the issuing CA if its [=attestation private key|private key=] has been compromised. A WebAuthn
Authenticator manufacturer may need to ship a firmware update and inject new [=attestation private keys=]
and [=attestation certificate|certificates=] into already
manufactured [=[WAA]s=], if the exposure was due to a firmware flaw. (The process by which this happens is out of
scope for this specification.) If the [=[WAA]=] manufacturer does not have this capability, then it may not be
possible for [=[RPS]=] to trust any further [=attestation statements=] from the affected [=[WAA]s=].

If an [=ECDAA=] [=attestation private key=] has been compromised, it can be added to the RogueList (i.e., the list of revoked
authenticators) maintained by the related ECDAA-Issuer.

See also the related security consideration for [=[RPS]=] in [[#sctn-revoked-attestation-certificates]].


## Security considerations for [=clients=] ## {#sctn-security-considerations-client}

### Browser Permissions Framework and Extensions ### {#sctn-browser-permissions-framework-extensions}

Web Authentication API implementations SHOULD leverage the browser permissions framework
[[Permissions]] when obtaining user
permissions for certain extensions. An example is the location extension (see [[#sctn-location-extension]]), implementations of
which MUST make use of the existing browser permissions framework for the Geolocation API,
as prescribed in [[!Geolocation-API]].


## Security considerations for [=[RPS]=] ## {#sctn-security-considerations-rp}

### Cryptographic Challenges ### {#sctn-cryptographic-challenges}

As a cryptographic protocol, Web Authentication is dependent upon randomized challenges
to avoid replay attacks. Therefore, the values of both {{PublicKeyCredentialCreationOptions}}.{{PublicKeyCredentialCreationOptions/challenge}} and {{PublicKeyCredentialRequestOptions}}.{{PublicKeyCredentialRequestOptions/challenge}} MUST be randomly generated
by [=[RPS]=] in an environment they trust (e.g., on the server-side), and the
returned {{CollectedClientData/challenge}} value in the client's
response MUST match what was generated. This SHOULD be done in a fashion that does not rely
upon a client's behavior, e.g., the Relying Party SHOULD store the challenge temporarily
until the operation is complete. Tolerating a mismatch will compromise the security
of the protocol.

In order to prevent replay attacks, the challenges MUST contain enough entropy to make guessing them infeasible. Challenges SHOULD
therefore be at least 16 bytes long.

### Security Benefits for [WRPS] ### {#sctn-rp-benefits}

The main benefits offered to [=[WRPS]=] by this specification include:

1. Users and accounts can be secured using widely compatible, easy-to-use multi-factor authentication.
1. The [=[RP]=] does not need to provision [=authenticator=] hardware to its users. Instead, each user can independently obtain
    any conforming [=authenticator=] and use that same [=authenticator=] with any number of [=[RPS]=]. The [=[RP]=] can optionally
    enforce requirements on [=authenticators=]' security properties by inspecting the [=attestation statements=] returned from the
    [=authenticators=].
1. [=Authentication ceremonies=] are resistant to [=man-in-the-middle attacks=].
    Regarding [=registration ceremonies=], see [[#sctn-attestation-limitations]], below.
1. The [=[RP]=] can automatically support multiple types of [=user verification=] - for example PIN, biometrics and/or future
    methods - with little or no code change, and can let each user decide which they prefer to use via their choice of
    [=authenticator=].
1. The [=[RP]=] does not need to store additional secrets in order to gain the above benefits.

As stated in the [[#sctn-conforming-relying-parties|Conformance]] section, the [=[RP]=] MUST behave as described in [[#sctn-rp-operations]]
to obtain all of the above security benefits. However, one notable use case that departs slightly from this is described in the
next section.


### Attestation Limitations ### {#sctn-attestation-limitations}

[INFORMATIVE]

When [[#sctn-registering-a-new-credential|registering a new credential]], the [=attestation statement=], if present,
may allow the [=[WRP]=] to derive assurances about various [=authenticator=] qualities.
For example, the [=authenticator=] model, or how it stores and protects [=credential private keys=].
However, it is important to note that an [=attestation statement=], on its own,
provides no means for a [=[RP]=] to verify that an [=attestation object=] was generated
by the [=authenticator=] the user intended, and not by a [=man-in-the-middle attack|man-in-the-middle attacker=].
For example, such an attacker could use malicious code injected into [=[RP]=] script.
The [=[RP]=] must therefore rely on other means, e.g., TLS and related technologies,
to protect the [=attestation object=] from [=man-in-the-middle attacks=].

Under the assumption that a [=registration ceremony=] is completed securely, and that the [=authenticator=] maintains
confidentiality of the [=credential private key=], subsequent [=authentication ceremonies=] using that [=public key
credential=] are resistant to [=man-in-the-middle attacks=].

The discussion above holds for all [=attestation types=]. In all cases it is possible for a [=man-in-the-middle
attack|man-in-the-middle attacker=] to replace the {{PublicKeyCredential}} object, including the [=attestation statement=] and the
[=credential public key=] to be registered, and subsequently tamper with future [=authentication assertions=] [=scoped=] for the
same [=[RP]=] and passing through the same attacker.

Such an attack would potentially be detectable; since the [=[RP]=] has registered the attacker's [=credential public key=] rather
than the user's, the attacker must tamper with all subsequent [=authentication ceremonies=] with that [=[RP]=]: unscathed
ceremonies will fail, potentially revealing the attack.

[=Attestation types=] other than [=Self Attestation=] and [=None=] can increase the difficulty of such attacks, since [=[RPS]=]
can possibly display [=authenticator=] information, e.g., model designation, to the user. An attacker might therefore need to use
a genuine [=authenticator=] of the same model as the user's [=authenticator=], or the user might notice that the [=[RP]=] reports
a different [=authenticator=] model than the user expects.

Note: All variants of [=man-in-the-middle attacks=] described above are more difficult for an attacker to mount
than a [=man-in-the-middle attack=] against conventional password authentication.


### Revoked Attestation Certificates ### {#sctn-revoked-attestation-certificates}

If [=attestation certificate=] validation fails due to a revoked intermediate attestation CA certificate, and the [=[RP]=]'s policy
requires rejecting the registration/authentication request in these situations, then it is RECOMMENDED that the [=[RP]=] also
un-registers (or marks with a trust level equivalent to "[=self attestation=]") [=public key credentials=] that were registered
after the CA compromise date using an [=attestation certificate=] chaining up to the same intermediate CA. It is thus RECOMMENDED
that [=[RPS]=] remember intermediate attestation CA certificates during [=registration=] in order to un-register
related [=public key credentials=] if the [=registration=] was performed after revocation of such certificates.

If an [=ECDAA=] [=attestation private key=] has been compromised, it can be added to the RogueList (i.e., the list of revoked
authenticators) maintained by the related ECDAA-Issuer. The [=[RP]=] SHOULD verify whether an [=authenticator=] belongs to the
RogueList when performing ECDAA-Verify (see section 3.6 in [[!FIDOEcdaaAlgorithm]]). For example, the FIDO Metadata Service
[[FIDOMetadataService]] provides one way to access such information.

See also the related security consideration for [=authenticators=] in [[#sctn-ca-compromise]].


### Credential Loss and Key Mobility ### {#sctn-credential-loss-key-mobility}

This specification defines no protocol for backing up [=credential private keys=], or for sharing them between [=authenticators=].
In general, it is expected that a [=credential private key=] never leaves the [=authenticator=] that created it. Losing an
[=authenticator=] therefore, in general, means losing all [=public key credential|credentials=] [=bound credential|bound=] to the
lost [=authenticator=], which could lock the user out of an account if the user has only one [=public key credential|credential=]
registered with the [=[RP]=]. Instead of backing up or sharing private keys, the Web Authentication API allows registering
multiple [=public key credential|credentials=] for the same user. For example, a user might register [=platform credentials=] on
frequently used [=client devices=], and one or more [=roaming credentials=] for use as backup and with new or rarely used [=client
devices=].

[=[RPS]=] SHOULD allow and encourage users to register multiple [=public key credential|credentials=] to the same account.
[=[RPS]=] SHOULD make use of the <code>{{PublicKeyCredentialCreationOptions/excludeCredentials}}</code> and
<code>{{PublicKeyCredentialCreationOptions/user}}.{{PublicKeyCredentialUserEntity/id}}</code> options to ensure that these
different [=public key credential|credentials=] are [=bound credential|bound=] to different [=authenticators=].



# Privacy Considerations # {#sctn-privacy-considerations}

The privacy principles in [[!FIDO-Privacy-Principles]] also apply to this specification.

This section is divided by audience;
general privacy considerations are direct subsections of this section,
while privacy considerations specifically for [=authenticator=], [=client=] and [=[RP]=] implementers
are grouped into respective subsections.


## De-anonymization Prevention Measures ## {#sctn-privacy-attacks}

[INFORMATIVE]

Many aspects of the design of the [=Web Authentication API=] are motivated by privacy concerns. The main concern considered in
this specification is the protection of the user's personal identity, i.e., the identification of a human being or a correlation
of separate identities as belonging to the same human being. Although the [=Web Authentication API=] does not use or provide any
form of global identity, the following kinds of potentially correlatable identifiers are used:

- The user's [=credential IDs=] and [=credential public keys=].

    These are registered by the [=[WRP]=] and subsequently used by the user to prove possession of the corresponding [=credential
    private key=]. They are also visible to the [=client=] in the communication with the [=authenticator=].

- The user's identities specific to each [=[RP]=], e.g., usernames and [=user handles=].

    These identities are obviously used by each [=[RP]=] to identify a user in their system. They are also visible to the
    [=client=] in the communication with the [=authenticator=].

- The user's biometric characteristic(s), e.g., fingerprints or facial recognition data [[ISOBiometricVocabulary]].

    This is optionally used by the [=authenticator=] to perform [=user verification=]. It is not revealed to the [=[RP]=], but in
    the case of [=platform authenticators=], it might be visible to the [=client=] depending on the implementation.

- The models of the user's [=authenticators=], e.g., product names.

    This is exposed in the [=attestation statement=] provided to the [=[RP]=] during [=registration=]. It is also visible to the
    [=client=] in the communication with the [=authenticator=].

- The identities of the user's [=authenticators=], e.g., serial numbers.

    This is possibly used by the [=client=] to enable communication with the [=authenticator=], but is not exposed to the
    [=[RP]=].

Some of the above information is necessarily shared with the [=[RP]=]. The following sections describe the measures taken to
prevent malicious [=[RPS]=] from using it to discover a user's personal identity.


## Anonymous, Scoped, Non-correlatable [=Public Key Credentials=] ## {#sctn-non-correlatable-credentials}

[INFORMATIVE]

Although [=Credential IDs=] and [=credential public keys=] are necessarily shared with the [=[WRP]=] to enable strong
authentication, they are designed to be minimally identifying and not shared between [=[RPS]=].

- [=Credential IDs=] and [=credential public keys=] are meaningless in isolation, as they only identify [=credential key pairs=]
    and not users directly.

- Each [=public key credential=] is strictly [=scoped=] to a specific [=[RP]=], and the [=client=] ensures that its existence is not
    revealed to other [=[RPS]=]. A malicious [=[RP]=] thus cannot ask the [=client=] to reveal a user's other identities.

- The [=client=] also ensures that the existence of a [=public key credential=] is not revealed to the [=[RP]=] without [=user
    consent=]. This is detailed further in [[#sctn-make-credential-privacy]] and [[#sctn-assertion-privacy]]. A malicious [=[RP]=]
    thus cannot silently identify a user, even if the user has a [=public key credential=] registered and available.

- [=Authenticators=] ensure that the [=credential IDs=] and [=credential public keys=] of different [=public key credentials=] are
    not correlatable as belonging to the same user. A pair of malicious [=[RPS]=] thus cannot correlate users between their
    systems without additional information, e.g., a willfully reused username or e-mail address.

- [=Authenticators=] ensure that their [=attestation certificates=] are not unique enough to identify a single [=authenticator=]
    or a small group of [=authenticators=]. This is detailed further in [[#sctn-attestation-privacy]]. A pair of malicious
    [=[RPS]=] thus cannot correlate users between their systems by tracking individual [=authenticators=].

Additionally, a [=client-side-resident public key credential source=] can optionally include a [=user
handle=] specified by the [=[RP]=]. The [=public key credential|credential=] can then be used to both identify and
[=authentication|authenticate=] the user. This means that a privacy-conscious [=[RP]=] can allow the user to create an account
without a traditional username, further improving non-correlatability between [=[RPS]=].


## Authenticator-local [=Biometric Recognition=] ## {#sctn-biometric-privacy}

[=Biometric authenticators=] perform the [=biometric recognition=] internally in the [=authenticator=] - though for [=platform
authenticators=] the biometric data might also be visible to the [=client=], depending on the implementation. Biometric data is
not revealed to the [=[WRP]=]; it is used only locally to perform [=user verification=] authorizing the creation and
[=registration=] of, or [=authentication=] using, a [=public key credential=]. A malicious [=[RP]=] therefore cannot discover the
user's personal identity via biometric data, and a security breach at a [=[RP]=] cannot expose biometric data for an attacker to
use for forging logins at other [=[RPS]=].

In the case where a [=[RP]=] requires [=biometric recognition=], this is performed locally by the [=biometric authenticator=]
perfoming [=user verification=] and then signaling the result by setting the [=UV=] [=flag=] in the signed [=assertion=] response,
instead of revealing the biometric data itself to the [=[RP]=].


## Privacy considerations for [=authenticators=] ## {#sctn-privacy-considerations-authenticator}

### Attestation Privacy ### {#sctn-attestation-privacy}

[=Attestation certificates=] and [=attestation key pairs=] and can be used to track users
or link various online identities of the same user together.
This can be mitigated in several ways, including:

- A [=[WAA]=] manufacturer may choose to ship [=authenticators=] in batches
    where [=authenticators=] in a batch share the same [=attestation certificate=] (called [=Basic Attestation=] or [=batch attestation=]).
    This will anonymize the user at the risk of not being able to revoke a particular [=attestation certificate=]
    if its [=attestation private key|private key=] is compromised.
    The [=authenticator=] manufacturer SHOULD then ensure that such batches are large enough to provide meaningful anonymization,
    while also minimizing the batch size in order to limit the number of affected users
    in case an [=attestation private key=] is compromised.

    [[UAFProtocol]] requires that at least 100,000 [=authenticator=] devices share the same [=attestation certificate=] in order to produce
    sufficiently large groups. This may serve as guidance about suitable batch sizes.

- A [=[WAA]=] may be capable of dynamically generating different [=attestation key pairs=] (and requesting related
    [=attestation certificate|certificates=]) per-[=origin=]
    (similar to the [=Attestation CA=] approach). For example, an [=authenticator=] can ship with a
    master [=attestation private key=] (and [=attestation certificate|certificate=]),
    and combined with a cloud-operated <dfn>Anonymization CA</dfn>,
    can dynamically generate per-[=origin=] [=attestation key pairs=] and [=attestation certificates=].

    Note: In various places outside this specification, the term "Privacy CA" is used to refer to what is termed here
        as an [=Anonymization CA=]. Because the Trusted Computing Group (TCG) also used the term "Privacy CA" to refer to what
        the TCG now refers to as an [=Attestation CA=] (ACA) [[!TCG-CMCProfile-AIKCertEnroll]], and the envisioned functionality
        of an [=Anonymization CA=] is not firmly established, we are using the term [=Anonymization CA=] here to try to mitigate
        confusion in the specific context of this specification.

- A [=[WAA]=] can implement [=Elliptic Curve based direct anonymous attestation=] (see [[FIDOEcdaaAlgorithm]]).
    Using this scheme, the authenticator generates a blinded [=attestation signature=]. This allows the [=[WRP]=] to verify the
    signature using the [=ECDAA-Issuer public key=], but the [=attestation signature=] does not serve as a global correlation handle.


### Privacy of [PII] Stored in Authenticators ### {#sctn-pii-privacy}

[=Authenticators=] MAY provide additional information to [=clients=] outside what's defined by this specification, e.g.,
to enable the [=client=] to provide a rich UI with which the user can pick which [=credential=] to use for an [=authentication
ceremony=]. If an [=authenticator=] chooses to do so, it SHOULD NOT expose [PII] unless successful [=user verification=] has been
performed. If the [=authenticator=] supports [=user verification=] with more than one concurrently enrolled user, the
[=authenticator=] SHOULD NOT expose [PII] of users other than the currently [=user verified|verified=] user. Consequently, an
[=authenticator=] that is not capable of [=user verification=] SHOULD NOT store [PII].

For the purposes of this discussion, the [=user handle=] conveyed as the {{PublicKeyCredentialUserEntity/id}} member of
{{PublicKeyCredentialUserEntity}} is not considered [PII]; see [[#sctn-user-handle-privacy]].

These recommendations serve to prevent an adversary with physical access to an [=authenticator=] from extracting [PII] about the
[=authenticator=]'s enrolled user(s).


## Privacy considerations for [=clients=] ## {#sctn-privacy-considerations-client}

### Registration Ceremony Privacy ### {#sctn-make-credential-privacy}

In order to protect users from being identified without [=user consent|consent=], implementations of the
{{PublicKeyCredential/[[Create]](origin, options, sameOriginWithAncestors)}} method need to take care to not leak information that
could enable a malicious [=[WRP]=] to distinguish between these cases, where "excluded" means that at least one of the [=public key
credential|credentials=] listed by the [=[RP]=] in {{PublicKeyCredentialCreationOptions/excludeCredentials}} is [=bound credential|bound=] to the
[=authenticator=]:

- No [=authenticators=] are present.
- At least one [=authenticator=] is present, and at least one present [=authenticator=] is excluded.

If the above cases are distinguishable, information is leaked by which a malicious [=[RP]=] could identify the user by probing for
which [=public key credential|credentials=] are available. For example, one such information leak is if the client returns a
failure response as soon as an excluded [=authenticator=] becomes available. In this case - especially if the excluded
[=authenticator=] is a [=platform authenticator=] - the [=[RP]=] could detect that the [=ceremony=] was canceled before the
timeout and before the user could feasibly have canceled it manually, and thus conclude that at least one of the [=public key
credential|credentials=] listed in the {{PublicKeyCredentialCreationOptions/excludeCredentials}} parameter is available to the user.

The above is not a concern, however, if the user has [=user consent|consented=] to create a new credential before a
distinguishable error is returned, because in this case the user has confirmed intent to share the information that would be
leaked.


### Authentication Ceremony Privacy ### {#sctn-assertion-privacy}

In order to protect users from being identified without [=user consent|consent=], implementations of the
{{PublicKeyCredential/[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)}} method need to take care to not
leak information that could enable a malicious [=[WRP]=] to distinguish between these cases, where "named" means that the [=public
key credential|credential=] is listed by the [=[RP]=] in {{PublicKeyCredentialRequestOptions/allowCredentials}}:

- A named [=public key credential|credential=] is not available.
- A named [=public key credential|credential=] is available, but the user does not [=user consent|consent=] to use it.

If the above cases are distinguishable, information is leaked by which a malicious [=[RP]=] could identify the user by probing
for which [=public key credential|credentials=] are available. For example, one such information leak is if the client returns a
failure response as soon as the user denies [=user consent|consent=] to proceed with an [=authentication ceremony=]. In this
case the [=[RP]=] could detect that the [=ceremony=] was canceled by the user and not the timeout, and thus conclude that at least
one of the [=public key credential|credentials=] listed in the {{PublicKeyCredentialRequestOptions/allowCredentials}} parameter is
available to the user.


### Privacy Between Operating System Accounts ### {#sctn-os-account-privacy}

If a [=platform authenticator=] is included in a [=client device=] with a multi-user operating system, the [=platform
authenticator=] and [=client device=] SHOULD work together to ensure that the existence of any [=platform credential=] is revealed
only to the operating system user that created that [=platform credential=].


## Privacy considerations for [=[RPS]=] ## {#sctn-privacy-considerations-rp}

### User Handle Contents ### {#sctn-user-handle-privacy}

Since the [=user handle=] is not considered [PII] in [[#sctn-pii-privacy]], the [=[RP]=] MUST NOT include [PII], e.g., e-mail
addresses or usernames, in the [=user handle=]. This includes hash values of [PII], unless the hash
function is [=salted=] with [=salt=] values private to the [=[RP]=], since hashing does not prevent probing for guessable input
values. It is RECOMMENDED to let the [=user handle=] be 64 random bytes, and store this value in the user's account.


### Username Enumeration ### {#sctn-username-enumeration}

While initiating a [=registration ceremony|registration=] or [=authentication ceremony=], there is a risk that the [=[WRP]=] might leak sensitive
information about its registered users. For example, if a [=[RP]=] uses e-mail addresses as usernames and an attacker attempts to
initiate an [=authentication=] [=ceremony=] for "alex.p.mueller@example.com" and the [=[RP]=] responds with a failure, but then
successfully initiates an [=authentication ceremony=] for "j.doe@example.com", then the attacker can conclude that "j.doe@example.com"
is registered and "alex.p.mueller@example.com" is not. The [=[RP]=] has thus leaked the possibly sensitive information that
"j.doe@example.com" has an account at this [=[RP]=].

The following is a non-normative, non-exhaustive list of measures the [=[RP]=] may implement to mitigate or prevent information
leakage due to such an attack:

- For [=registration ceremonies=]:

    - If the [=[RP]=] uses [=[RP]=]-specific usernames to identify users:

        - When initiating a [=registration ceremony=], disallow registration of usernames that are syntactically valid e-mail
            addresses.

            Note: The motivation for this suggestion is that in this case the [=[RP]=] probably has no choice but to fail the
            [=registration ceremony=] if the user attempts to register a username that is already registered, and an information
            leak might therefore be unavoidable. By disallowing e-mail addresses as usernames, the impact of the leakage can be
            mitigated since it will be less likely that a user has the same username at this [=[RP]=] as at other [=[RPS]=].

    - If the [=[RP]=] uses e-mail addresses to identify users:

        - When initiating a [=registration ceremony=], interrupt the user interaction after the e-mail address is supplied and
            send a message to this address, containing an unpredictable one-time code and instructions for how to use it to
            proceed with the ceremony. Display the same message to the user in the web interface regardless of the contents of the
            sent e-mail and whether or not this e-mail address was already registered.

            Note: This suggestion can be similarly adapted for other externally meaningful identifiers, for example, national ID
            numbers or credit card numbers &mdash; if they provide similar out-of-band contact information, for example,
            conventional postal address.

- For [=authentication ceremonies=]:

    - If, when initiating an [=authentication ceremony=], there is no account matching the provided username, continue the
        ceremony by invoking {{CredentialsContainer/get()|navigator.credentials.get()}} using a syntactically valid
        {{PublicKeyCredentialRequestOptions}} object that is populated with plausible imaginary values.

        This approach could also be used to mitigate privacy leakage via {{PublicKeyCredentialRequestOptions/allowCredentials}};
        see [[#sctn-credential-id-privacy-leak]].

        Note: The username may be "provided" in various [=[RP]=]-specific fashions: login form, session cookie, etc.

        Note: If returned imaginary values noticeably differ from actual ones, clever attackers may be able to discern them and
            thus be able to test for existence of actual accounts. Examples of noticeably different values include if the values
            are always the same for all username inputs, or are different in repeated attempts with the same username input. The
            {{PublicKeyCredentialRequestOptions/allowCredentials}} member could therefore be populated with pseudo-random values
            derived deterministically from the username, for example.

    - When verifying an {{AuthenticatorAssertionResponse}} response from the [=authenticator=], make it indistinguishable whether
          verification failed because the signature is invalid or because no such user or credential is registered.

    - Perform a multi-step [=authentication ceremony=], e.g., beginning with supplying username and password or a session cookie,
        before initiating the WebAuthn [=ceremony=] as a subsequent step.
        This moves the username enumeration problem from the WebAuthn step
        to the preceding authentication step, where it may be easier to solve.


### Privacy leak via credential IDs ### {#sctn-credential-id-privacy-leak}

[INFORMATIVE]

This privacy consideration applies to [=[RPS]=] that support [=authentication ceremonies=]
with a non-[=list/empty=] {{PublicKeyCredentialRequestOptions/allowCredentials}} argument as the first authentication step.
For example, if using authentication with [=non-resident credentials=] as the first authentication step.

In this case the {{PublicKeyCredentialRequestOptions/allowCredentials}} argument risks leaking [PII],
since it exposes the user's [=credential IDs=] to an unauthenticated caller.
[=Credential IDs=] are designed to not be correlatable between [=[RPS]=],
but the length of a [=credential ID=] might be a hint as to what type of [=authenticator=] created it.
It is likely that a user will use the same username and set of [=authenticators=] for several [=[RPS]=],
so the number of [=credential IDs=] in {{PublicKeyCredentialRequestOptions/allowCredentials}} and their lengths
might serve as a global correlation handle to de-anonymize the user.
Knowing a user's [=credential IDs=] also makes it possible to confirm guesses about the user's identity
given only momentary physical access to one of the user's [=authenticators=].

In order to prevent such information leakage, the [=[RP]=] could for example:

- Perform a separate authentication step,
    such as username and password authentication or session cookie authentication,
    before initiating the WebAuthn [=authentication ceremony=] and exposing the user's [=credential IDs=].
- Use [=resident credentials=],
    so the {{PublicKeyCredentialRequestOptions/allowCredentials}} argument is not needed.

If the above prevention measures are not available,
i.e., if {{PublicKeyCredentialRequestOptions/allowCredentials}} needs to be exposed given only a username,
the [=[RP]=] could mitigate the privacy leak using the same approach of returning imaginary [=credential IDs=]
as discussed in [[#sctn-username-enumeration]].


# Acknowledgements # {#sctn-acknowledgements}
We thank the following people for their reviews of, and contributions to, this specification:
Yuriy Ackermann,
James Barclay,
Richard Barnes,
Dominic Battré,
John Bradley,
Domenic Denicola,
Rahul Ghosh,
Brad Hill,
Jing Jin,
Wally Jones,
Ian Kilpatrick,
Axel Nennker,
Yoshikazu Nojima,
Kimberly Paulhamus,
Adam Powers,
Yaron Sheffer,
Nick Steele,
Anne van Kesteren,
Johan Verrept,
and
Boris Zbarsky.

Thanks to Adam Powers for creating the overall [=registration=] and [=authentication=] flow diagrams
([Figure 1](#fig-registration) and [Figure 2](#fig-authentication)).

We thank
Anthony Nadalin,
John Fontana,
and
Richard Barnes
for their contributions as co-chairs of the <a href="https://www.w3.org/Webauthn/">Web Authentication Working Group</a>.

We also thank
Wendy Seltzer,
Samuel Weiler,
and
Harry Halpin
for their contributions as our W3C Team Contacts.


<pre class=biblio>
{

  "UTR29": {
    "href": "http://www.unicode.org/reports/tr29/",
    "title": "UNICODE Text Segmentation",
    "publisher": "UNICODE Consortium"
  },


  "IANA-COSE-ALGS-REG": {
    "href": "https://www.iana.org/assignments/cose/cose.xhtml#algorithms",
    "title": "IANA CBOR Object Signing and Encryption (COSE) Algorithms Registry",
    "publisher": "IANA"
  },


  "WebAuthnAPIGuide": {
    "href": "https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API",
    "title": "Web Authentication API Guide",
    "publisher": "MDN: Mozilla Developer Network",
    "status": "Experimental"
  },

  "Ceremony": {
    "title": "Ceremony Design and Analysis",
    "href": "https://eprint.iacr.org/2007/399.pdf",
    "authors": ["Carl Ellison"],
    "date": "2007"
  },

  "WebAuthn-Registries": {
    "authors": [
        "Jeff Hodges",
        "Giridhar Mandyam",
        "Michael B. Jones"
    ],
    "date": "October 2019",
    "href": "https://tools.ietf.org/html/draft-hodges-webauthn-registries",
    "publisher": "W3C WebAuthn Working Draft",
    "status": "Active Internet-Draft",
    "title": "Registries for Web Authentication (WebAuthn)",
    "id": "WebAuthn-Registries"
  },

  "WebAuthn-COSE-Algs": {
    "authors": [
        "Michael B. Jones"
    ],
    "date": "May 2018",
    "href": "https://tools.ietf.org/html/draft-jones-webauthn-cose-algorithms",
    "publisher": "W3C WebAuthn Working Draft",
    "status": "Active Internet-Draft",
    "title": "COSE Algorithms for Web Authentication (WebAuthn)",
    "id": "WebAuthn-COSE-Algs"
  },

  "SP800-800-63r3": {
    "title": "NIST Special Publication 800-63: Digital Identity Guidelines",
    "href": "https://pages.nist.gov/800-63-3/sp800-63-3.html",
    "authors": ["Paul A. Grassi", "Michael E. Garcia", "James L. Fenton"],
    "date": "June 2017"
  },

  "UAFProtocol": {
    "authors": ["R. Lindemann", "D. Baghdasaryan", "E. Tiffany", "D. Balfanz", "B. Hill", "J. Hodges"],
    "title": "FIDO UAF Protocol Specification v1.0",
    "status": "FIDO Alliance Proposed Standard",
    "href": "https://fidoalliance.org/specs/fido-uaf-v1.0-ps-20141208/fido-uaf-protocol-v1.0-ps-20141208.html"
  },

  "FIDOEcdaaAlgorithm": {
    "title": "FIDO ECDAA Algorithm",
    "authors": ["R. Lindemann", "Jan Camenisch", "Manu Drijvers", "Alec Edgington", "Anja Lehmann", "Rainer Urian"],
    "status": "FIDO Alliance Implementation Draft",
    "href": "https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-ecdaa-algorithm-v2.0-id-20180227.html",
    "status": "FIDO Alliance Implementation Draft",
    "date": "27 February 2018"
  },

  "SEC1": {
    "title": "SEC1: Elliptic Curve Cryptography, Version 2.0",
    "publisher": "Standards for Efficient Cryptography Group",
    "href": "http://www.secg.org/sec1-v2.pdf"
  },

  "FIDOMetadataService": {
    "authors": ["R. Lindemann", "B. Hill", "D. Baghdasaryan"],
    "title": "FIDO Metadata Service",
    "href": "https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-metadata-service-v2.0-id-20180227.html",
    "status": "FIDO Alliance Implementation Draft",
    "date": "27 February 2018"
  },

  "FIDOUAFAuthenticatorMetadataStatements": {
    "authors": ["B. Hill", "D. Baghdasaryan", "J. Kemp"],
    "title": "FIDO UAF Authenticator Metadata Statements v1.0",
    "href": "https://fidoalliance.org/specs/fido-uaf-v1.0-ps-20141208/fido-uaf-authnr-metadata-v1.0-ps-20141208.html",
    "status": "FIDO Alliance Proposed Standard"
  },

  "FIDOU2FJavaScriptAPI": {
    "authors": ["D. Balfanz", "A. Birgisson", "J. Lang"],
    "title": "FIDO U2F JavaScript API",
    "href": "https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-javascript-api-v1.2-ps-20170411.html",
    "status": "FIDO Alliance Proposed Standard"
  },

  "TPMv2-Part1": {
    "title": "Trusted Platform Module Library, Part 1: Architecture",
    "publisher": "Trusted Computing Group",
    "href": "https://www.trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-1-Architecture-01.38.pdf"
  },

  "TPMv2-Part2": {
    "title": "Trusted Platform Module Library, Part 2: Structures",
    "publisher": "Trusted Computing Group",
    "href": "https://www.trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-2-Structures-01.38.pdf"
  },

  "TPMv2-Part3": {
    "title": "Trusted Platform Module Library, Part 3: Commands",
    "publisher": "Trusted Computing Group",
    "href": "https://www.trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-3-Commands-01.38.pdf"
  },

  "TPMv2-EK-Profile": {
    "title": "TCG EK Credential Profile for TPM Family 2.0",
    "publisher": "Trusted Computing Group",
    "href": "https://www.trustedcomputinggroup.org/wp-content/uploads/Credential_Profile_EK_V2.0_R14_published.pdf"
  },

  "FIDOAuthnrSecReqs": {
    "authors": ["D. Biggs", "J.E. Hill", "L. Lundblade", "M. Karlsson"],
    "title": "FIDO Authenticator Security Requirements",
    "href": "https://fidoalliance.org/specs/fido-security-requirements-v1.0-fd-20170524/",
    "status": "FIDO Alliance Final Documents"
  },

  "FIDOSecRef": {
    "authors": ["R. Lindemann", "D. Baghdasaryan", "B. Hill", "Dr. J. E. Hill", "D. Biggs"],
    "title": "FIDO Security Reference",
    "href": "https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-security-ref-v2.0-id-20180227.html",
    "status": "FIDO Alliance Implementation Draft",
    "date": "27 February 2018"
  },

  "FIDO-Registry": {
    "authors": ["R. Lindemann", "D. Baghdasaryan", "B. Hill"],
    "title": "FIDO Registry of Predefined Values",
    "href": "https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-registry-v2.0-id-20180227.html",
    "status": "FIDO Alliance Implementation Draft",
    "date": "27 February 2018"
  },

  "FIDO-APPID": {
    "authors": ["D. Balfanz", "B. Hill", "R. Lindemann", "D. Baghdasaryan"],
    "title": "FIDO AppID and Facet Specification",
    "href": "https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-appid-and-facets-v2.0-id-20180227.html",
    "status": "FIDO Alliance Implementation Draft",
    "date": "27 February 2018"
  },

  "FIDO-U2F-Message-Formats": {
    "authors": ["D. Balfanz", "J. Ehrensvard", "J. Lang"],
    "title": "FIDO U2F Raw Message Formats",
    "href": "https://fidoalliance.org/specs/fido-u2f-v1.1-id-20160915/fido-u2f-raw-message-formats-v1.1-id-20160915.html",
    "status": "FIDO Alliance Implementation Draft"
  },

  "FIDO-CTAP": {
    "authors": ["M. Antoine", "V. Bharadwaj", "C. Brand", "A. Czeskis", "J. Ehrensvärd", "J. Hodges", "M. B. Jones", "A. Kumar",
        "R. Lindemann", "M. J. Ploch", "A. Powers", "J. Verrept"],
    "title": "Client to Authenticator Protocol",
    "href": "https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-client-to-authenticator-protocol-v2.0-id-20180227.html",
    "status": "FIDO Alliance Implementation Draft",
    "date": "27 February 2018"
  },

  "FIDO-UAF-AUTHNR-CMDS": {
    "authors": ["R. Lindemann", "J. Kemp"],
    "title": "FIDO UAF Authenticator Commands",
    "href": "https://fidoalliance.org/specs/fido-uaf-v1.1-id-20170202/fido-uaf-authnr-cmds-v1.1-id-20170202.html",
    "status": "FIDO Alliance Implementation Draft"
  },

  "FIDO-Privacy-Principles": {
    "authors": ["FIDO Alliance"],
    "title": "FIDO Privacy Principles",
    "href": "https://fidoalliance.org/wp-content/uploads/2014/12/FIDO_Alliance_Whitepaper_Privacy_Principles.pdf",
    "status": "FIDO Alliance Whitepaper"
  },

  "FIDO-Transports-Ext": {
    "authors": ["FIDO Alliance"],
    "title": "FIDO U2F Authenticator Transports Extension",
    "href": "https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-authenticator-transports-extension-v1.2-ps-20170411.html",
    "status": "FIDO Alliance Proposed Standard"
  },

  "RFC8610": {
    "authors": ["H. Birkholz", "C. Vigano", "C. Bormann"],
    "title": "Concise Data Definition Language (CDDL): A Notational Convention to Express Concise Binary Object Representation (CBOR) and JSON Data Structures",
    "href": "https://tools.ietf.org/html/rfc8610",
    "status": "IETF Proposed Standard",
    "date": "June 2019"
  },

  "ISOBiometricVocabulary": {
    "authors": ["ISO/IEC JTC1/SC37"],
    "title": "Information technology — Vocabulary — Biometrics",
    "href": "http://standards.iso.org/ittf/PubliclyAvailableStandards/c055194_ISOIEC_2382-37_2012.zip",
    "status": "International Standard: ISO/IEC 2382-37:2012(E) First Edition",
    "date": "15 December 2012"
  },

  "TokenBinding": {
    "authors": ["A. Popov", "M. Nystroem", "D. Balfanz", "J. Hodges"],
    "title": "The Token Binding Protocol Version 1.0",
    "href": "https://tools.ietf.org/html/rfc8471",
    "status": "IETF Proposed Standard",
    "date": "October, 2018"
  },

  "EduPersonObjectClassSpec": {
    "publisher": ["Internet2 Middleware Architecture Committee for Education, Directory Working Group (MACE-Dir)"],
    "title": "EduPerson Object Class Specification (200604a)",
    "href": "https://www.internet2.edu/media/medialibrary/2013/09/04/internet2-mace-dir-eduperson-200604.html",
    "date": "May 15, 2007"
  }

}
</pre>
